Комбинируем WP_Query и основной запрос

В большинстве случаев вы будете использовать WP_Query с полностью новым набором аргументов, отделенных от основного запроса. Но что если нам вдруг понадобится включить основной запрос в аргументы?

Такая комбинация может понадобиться в следующих ситуациях:

  • На странице категории или таксономии, для отображения записей одного типа;
  • Для отображения записей из текущей рубрики и другой категории, тега или таксономии;
  • Для отображения записей только с определенными мета-данными.

Задаем переменную на основе основного запроса

Так как мы собираемся комбинировать основной запрос с WP_Query, то нам придется хранить объект текущего запроса таким образом, чтобы его было проще использовать в аргументах WP_Query. Самый простой способ заключается в том, чтобы привязать его к переменной.

Это нужно сделать до определения аргументов WP_Query:

$mainquery = get_queried_object();

Функция get_queried_object() возвращает текущий опрашиваемый объект. В случае с отдельными записями, она будет возвращать объект записи, а при работе с архивами – объекты категории, тега, терминов, связанных с архивом. Она возвращает ID опрашиваемого объекта.

Вы можете использовать эту переменную $mainquery в своих аргументах WP_Query.

Пример 1: выводим записи одного типа на странице категории

Предположим, на вашем сайте имеется произвольный тип записи, и для записей этого типа вы используете категории. И вам не хочется показывать записи в архиве каждой категории. Вместо этого нужно вывести записи вашего нового типа, который назовем product.

В данном случае запрос будет выглядеть примерно следующим образом:

<?php

$mainquery = get_queried_object();

$args = array (
    'category_name' => $mainquery->slug,
    'post_type' => 'product'
);

// Произвольный запрос.
$query = new WP_Query( $args );

// Проверка наличия результатов запроса.
if ( $query->have_posts() ) {

    // Начало цикла обработки данных из результатов запроса.
    while ( $query->have_posts() ) {

        $query->the_post();

        // содержимое опрашиваемой записи.

    }

}

// восстановление исходных данных записи.
wp_reset_postdata();

?>

Параметр category_name в качестве аргумента принимает slug категории, поэтому необходимо после переменной добавить ->slug, чтобы вывести ярлык категории.

Таким образом, мы получим запрос, который извлекает из базы данных записи типа product из текущей категории. Такой запрос можно использовать в шаблоне страницы category.php.

Примечание: этого результата можно добиться, используя хук pre_get_posts для изменения основного запроса в комбинации с условной функцией для проверки архива категории.

Пример 2: объединяем основной запрос с WP_Query и foreach для вывода нескольких циклов

Следующий пример позволит нам вывести все записи на страницу текущей категории отсортированными по типам.

Это значит, что вы можете сортировать типы записей по блокам или колонкам при помощи CSS или вывести их в виде отдельных списков.

Чтобы получить необходимый результат, воспользуйтесь следующим кодом:

<?php

$mainquery = get_queried_object();

$post_types = get_post_types();

foreach ( $post_types as $post_type ) {

    $args = array(
        'category_name' => $mainquery->slug,
        'post_type' => $post_type
    );

    // Произвольный запрос.
    $query = new WP_Query( $args );

    // Проверка наличия результатов запроса.
    if ( $query->have_posts() ) {

        // начало цикла обработки данных из результатов запроса.
        while ( $query->have_posts() ) {

            $query->the_post();

            // содержимое опрашиваемой записи.

        }

    }

    // восстановление исходных данных записи.
    wp_reset_postdata();

}

?>

Здесь также используется переменная $mainquery, но при этом добавляется переменная $post_types, которая хранит в себе зарегистрированные на сайте типы записей, а также $post_type для хранения каждого отдельного типа записи.

Пример 3: два отдельных запроса для двух типов записей

Последний пример немного похож на предыдущий, но только разделяет типы записей на два отдельных запроса, в каждом из которых будет свой уникальный цикл. Таким образом, можно контролировать, что следует отображать в каждом из циклов. Благодаря этому можно не только вывести записи типа product, но и оформить их миниатюрой или задать им другой тип разметки.

Предположим, что на сайте зарегистрирован тип записи product, и он включен в категории, но в те же рубрики вы публикуете и обычные статьи. На каждой странице архива категории вам нужно показать 10 последних записей, а затем вывести список всех товаров из этой рубрики.

Этого можно добиться при помощи следующего кода:

<?php

$mainquery = get_queried_object();

// Аргументы первого запроса для записей.
$args = array (
    'category_name' => $mainquery->slug,
    'post_type' => 'post',
    'posts_per_page' => '10'
);

// Произвольный запрос.
$query = new WP_Query( $args );

// Проверка наличия результатов запроса.
if ( $query->have_posts() ) {

    // начало цикла обработки данных из результатов запроса.
    while ( $query->have_posts() ) {

        $query->the_post();

        // содержимое опрашиваемой записи.

    }

}

// восстановление исходных данных записи.
wp_reset_postdata();

// Аргументы второго запроса для товаров.
$args = array (
    'category_name' => $mainquery->slug,
    'post_type' => 'product',
    'posts_per_page' => '-1'
);

// Произвольный запрос.
$query = new WP_Query( $args );

// Проверка наличия результатов запроса.
if ( $query->have_posts() ) {

    // начало цикла обработки данных из результатов запроса.
    while ( $query->have_posts() ) {

        $query->the_post();

        // содержимое опрашиваемой записи.

    }

}

// восстановление исходных данных записи.
wp_reset_postdata();

?>

В завершение

WP_Query можно использовать не только для создания собственных запросов отдельно от основного запроса, но и опрашивать текущий объект и создавать многофункциональные запросы на страницах архива.

Приведенные примеры можно реализовать и для других типов архивов: таксономий, авторов, дат и т. д. Возможно, вы придумаете что-нибудь другое, но тогда не забудьте рассказать об этом в комментариях!

РедакцияПеревод статьи «Combining WP_Query With the Main Query»