Аргументы WP_Query: статус, порядок и пагинация

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

  • статусу;
  • порядку;
  • пагинации.

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

Вспоминаем, как работают аргументы в WP_Query

Когда вы используете WP_Query в собственных темах оформления или плагинах, приходится включать в код четыре основных элемента:

  • Аргументы для запроса, в которых используются параметры;
  • Сам запрос;
  • Цикл;
  • Завершающий этап: сброс данных записи.

На практике это выглядит следующим образом:

<?php
 
$args = array(
    // Аргументы для вашего запроса
);
 
// Произвольный запрос
$query = new WP_Query( $args );
 
// Проверка наличия результатов запроса
if ( $query->have_posts() ) {
 
    // начало цикла обработки данных из результатов запроса
    while ( $query->have_posts() ) {
 
        $query->the_post();
 
        // содержимое опрашиваемой записи 
 
    }
 
}
 
// восстановление исходных данных записи
wp_reset_postdata();
 
?>

Аргументы сообщают WordPress, какие данные нужно извлекать из базы данных. Давайте сосредоточим внимание на самом начале кода:

$args = array(
    // Аргументы для вашего запроса
);

Как видно, аргументы заключены в массив.

Создаем код для аргументов

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

$args = array(
    'parameter1' => 'value',
    'parameter2' => 'value',
    'parameter3' => 'value'
);

Вам следует заключать параметры и их значения в одинарные кавычки, а также использовать => между ними. Аргументы разделяются запятой. Если не соблюдать установленный синтаксис, то WordPress может опросить не все указанные вами аргументы, и в итоге на экран ничего не выведется.

Параметры статуса

Как вы знаете, WordPress задает каждой записи отдельный статус. Можно использовать параметр post_status для запросов записей с одним или несколькими статусами.

Доступны следующие аргументы:

  • publish: опубликованная запись или страница;
  • pending: запись ожидает рассмотрения;
  • draft: запись в статусе черновика;
  • auto-draft: только что созданная запись, без какого-либо контента;
  • future: запланированная запись;
  • private: запись не видна посетителям, которые не авторизовались на сайте;
  • inherit: измененная версия записи или статус для прикрепленных записей;
  • trash: запись находится в корзине;
  • any: запрашивает любой статус, за исключением тех, у которых параметр ‘exclude_from_search’ выставлен на true (например, auto-draft или trash).

Если вы не укажете статус в аргументах вашего запроса, WordPress по умолчанию будет ориентироваться на publish; если пользователь авторизован на сайте, то в запросе также будут учитываться записи со статусом private. Если вы запускаете запрос от имени администратора, то WordPress также будет учитывать защищенные статусы: future, draft и pending.

Предположим, что у вас есть сайт-афиша, на котором используется собственный тип записей event, и в качестве даты публикации используется дата, на которую запланировано то или иное мероприятие. По умолчанию, WordPress не будет отображать еще не состоявшиеся события. Несмотря на то, что вы запланировали, дата публикации находится в будущем, а, значит, статус записи будет future.

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

$args = array(
    'post_type' => 'event',
    'post_status' => 'future'
);

Этот код позволит отобразить те события, которые еще не состоялись, так как для опубликованных записей используется статус publish. Но если необходимо показать и состоявшиеся мероприятия, то нужно использовать массив, в котором указано больше одного статуса:

$args = array(
    'post_type' => 'event',
    'post_status' => array(
        'future',
        'publish'
    )
);

Параметр post_status важен при осуществлении запросов к вложениям, потому что используется статус inherit, а не publish. Чтобы осуществить запрос всех вложений, можно использовать следующий код:

$args = array(
    'post_type' => 'attachment',
    'post_status' => 'inherit'
);

Но вы можете заменить inherit на любой другой статус, который позволит получить аналогичный результат.

Параметры сортировки

Существует два параметра, которые можно использовать для сортировки записей, полученных при помощи WP_Query: order и orderby. Как вы уже поняли, order определяет порядок, в котором записи выводятся в цикле, а orderby определяет, по какому полю в базе данных они будут сортироваться.

Параметр order

Есть всего аргумента, которые можно использовать для сортировки:

ASC: по возрастанию (1, 2, 3; a, b, c).
DESC: по убыванию (3, 2, 1; c, b, a).

Если вы не включите аргумент для order, по умолчанию WordPress будет использовать DESC.

Параметр orderby

Вы можете сортировать записи по нескольким полям:

  • none: нет условий сортировки (доступно с версии 2.8);
  • ID: сортировка по id записи. Не забывайте про верхний регистр;
  • author: сортировка по автору;
  • title: сортировка по заголовку;
  • name: сортировка по slug записи;
  • type: сортировка по типу записи;
  • date: сортировка по дате;
  • modified: сортировка по последней дате изменения;
  • parent: сортировка по id родительской записи/страницы;
  • rand: случайный порядок;
  • comment_count: сортировка по количеству комментариев;
  • menu_order: сортировка по порядку расположения страниц. Наиболее часто используется для страниц (здесь используется значение, которое указывается в мета-блоке при редактировании страницы), а также для вложений (используется целое число из диалогового окна Вставка / Загрузить медиафайл). Также можно использовать для любого типа записи с включенным параметром menu_order;
  • meta_value: сортировка по значению мета-ключа или пользовательского;
  • поля: Будет работать только в том случае, если установлен параметр meta_key. Мета-значения сортируются по алфавиту, а не по числам (то есть 34 выведется раньше цифры 4);
  • meta_value_num: сортировка по числовому мета-значению. Как и в случае с meta_value, в запросе должен использоваться аргумент meta_key;
  • post__in: сохраняет сортировку по ID записей, выставленную в массиве post__in.

По умолчанию, для сортировки используется поле date. То есть, сортируется по дате публикации.

Если нужно сортировать записи по заголовку в порядке убывания, то можно использовать следующие аргументы:

$args = array(
    'orderby' => 'title',
    'order' => 'ASC'
);

Сортировка по нескольким полям

Чтобы отсортировать записи по нескольким полям, нужно воспользоваться массивом с параметром orderby и с параметром order, если нужна сортировка каждого поля в разном порядке.

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

$args = array(
    'orderby' => array(
        'meta_value_num',
        'title'
    ),
    'order' => 'ASC',
    'meta_key' => 'rating'
);

Я включила в запрос аргумент meta_key, и это позволит WordPress понять, какое произвольное поле мы используем. Это нужно делать именно потому, что WordPress хранит метаданные записей в таблице wp_postmeta, а не в wp_posts.

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

$args = array(
    'orderby' => array(
        'meta_value_num',
        'title'
    ),
    'order' => array(
        'DESC',
        'ASC'
    ),
    'meta_key' => 'rating'
);

Также можно выполнить сортировку по нескольким полям, если не требуется использовать метаданные записи. Например, чтобы сортировать записи по типу, а затем по дате, можно использовать следующий код:

$args = array(
    'orderby' => array(
        'type',
        'date'
    ),
    'order' => array(
        'ASC',
        'DESC'
    )
);

Этот код позволит осуществить сортировку по типу записи в возрастающем порядке, а затем, в рамках каждого типа записи, по дате в порядке убывания.

Параметры пагинации

Мы переходим к еще одному набору параметров, который связан с постраничным выводом контента, с пагинацией. Эти параметры помогают определять, сколько записей будет опрошено, и как будет происходить нумерация страниц.

Доступны следующие параметры:

  • nopaging (boolean): отображать все записи или использовать пагинацию. По умолчанию выставлено значение ‘false’, то есть, используется постраничный вывод;
  • posts_per_page (int): количество записей на странице;
  • posts_per_archive_page (int): количество записей на странице, но только на странице архива;
  • offset (int): количество записей, после которого начинается вывод;
  • paged (int): страница в архиве, из которого выводятся страницы;
  • page (int): количество страниц для статичной главной страницы. Отображение записей, которые должны в обычном режиме показываться только на странице Х при включении статичной главной страницы (Front Page);
  • ignore_sticky_posts (boolean): игнорируем прикрепленные записи. По умолчанию используется значение false.

Количество записей и пропуск записей

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

$args = array(
    'posts_per_page' => '5'
);

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

$args = array(
    'posts_per_page' => '5',
    'offset' => '1'
);

Учтите, что, несмотря на то, что вы извлекаете записи из шести последних записей в базе данных, вы по-прежнему используете ‘posts_per_page’ => ‘5’, так как именно такое количество записей должно быть отображено.

Можно создать два запроса: один для отображения самых свежих записей, а второй – для отображения еще 10 записей, за исключением той записи:

$args = array(
    'posts_per_page' => '1'
);
 
// Здесь начинается запрос и цикл, а также сброс записей.
 
$args = array(
    'posts_per_page' => '10',
    'offset' => '1'
);
 
// Здесь идет второй запрос, цикл, и сброс.

Для отображения всех записей можно использовать posts_per_page:

$args = array(
    'posts_per_page' => '-1'
);

Прикрепленные записи

Обычно прикрепленные записи отображаются первыми в любом запросе. Если нужно переопределить эту установку, то воспользуйтесь параметром ignore_sticky_posts:

$args = array(
    'posts_per_page' => '5',
    'ignore_sticky_posts' => true
);

Приведенные выше аргументы позволят получить последние пять записей, независимо от того, являются они прикрепленными или нет.

Если нужно отобразить только прикрепленные записи, то нужно использовать функцию get_option() и аргумент post__in следующим образом:

$sticky = get_option( 'sticky_posts' );
 
$args = array(
    'posts_per_page' => '5',
    'post__in' => $sticky
);

Приведенный выше код позволит получить пять последних прикрепленных записей. Если их будет меньше пяти (например, три), то будет выведено только доступное количество прикрепленных записей.

Пагинация в архивах

Также можно использовать параметры пагинации для того, чтобы определить, каким образом полученные записи будут распределяться по нескольким страницам архива или на страницах поисках.

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

$args = array(
    'posts_per_archive_page' => '20'
);

Примечание: аргумент posts_per_archive_page переопределяет posts_per_page.

Также можно вывести те страницы, которые должны отображаться на определенной странице из пагинации. Если нужно показать 20 записей, которые находятся на третьей странице из примера выше, то следует воспользоваться следующим кодом:

$args = array(
    'posts_per_archive_page' => '20',
    'paged' => '3'
);

Также можно использовать аргумент offset:

$args = array(
    'posts_per_page' => '20',
    'offset' => '40'
);

Этот запрос пропустит 40 записей, которые расположены на первых двух страницах архива, и извлечет следующие 20 (с третьей страницы).

Также можно полностью отключить пагинацию, и тогда все записи будут отображены на одной странице:

$args = array(
    'nopaging' => true
);

В завершение

Класс WP_Query является достаточно гибким с точки зрения определения количества записей для запроса, их сортировки и статуса.

Некоторые аргументы удобно использовать в запросах к определенным типам записей. Например, аргумент ‘post_status’ => ‘inherited’ при работе с вложениями. А с помощью остальных можно контролировать выполнение самих запросов.

Перевод статьи “WP_Query Arguments: Status, Order and Pagination” был подготовлен дружной командой проекта Сайтостроение от А до Я.