Знакомство с WP_Query

Выбирает записи из базы данных по указанным критериям. На основе WP_Query работают функции get_posts() и query_posts() и все остальные запросы связанные с выбором записей из таблицы wp_posts.

Оглавление ▴
Используется в: wp_playlist_shortcode()get_posts().
Хуки из класса:
 
do_action_ref_array( 'parse_query', array( &$this ) );
do_action( 'parse_tax_query', $this );
$this->stopwords = apply_filters( 'wp_search_stopwords', $stopwords );
do_action_ref_array( 'pre_get_posts', array( &$this ) );
$search = apply_filters_ref_array( 'posts_search', array( $search, &$this ) );
$search_orderby = apply_filters( 'posts_search_orderby', $search_orderby, $this );
$where = apply_filters_ref_array( 'posts_where', array( $where, &$this ) );
$join = apply_filters_ref_array( 'posts_join', array( $join, &$this ) );
$cjoin = apply_filters_ref_array( 'comment_feed_join', array( $cjoin, &$this ) );
$cwhere = apply_filters_ref_array( 'comment_feed_where', array( $cwhere, &$this ) );
$cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( $cgroupby, &$this ) );
$corderby = apply_filters_ref_array( 'comment_feed_orderby', array( 'comment_date_gmt DESC', &$this ) );
$climits = apply_filters_ref_array( 'comment_feed_limits', array( 'LIMIT ' . get_option('posts_per_rss'), &$this ) );$where = apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) );$groupby = apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) );
$join = apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) );
$orderby = apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) );
$distinct = apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) );
$limits = apply_filters_ref_array( 'post_limits', array( $limits, &$this ) );
$fields = apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) );
$clauses = (array) apply_filters_ref_array( 'posts_clauses', array( compact( $pieces ), &$this ) );
do_action( 'posts_selection', $where . $groupby . $orderby . $limits . $join );
$where = apply_filters_ref_array( 'posts_where_request', array( $where, &$this ) );
$groupby = apply_filters_ref_array( 'posts_groupby_request', array( $groupby, &$this ) );
$join = apply_filters_ref_array( 'posts_join_request', array( $join, &$this ) );
$orderby = apply_filters_ref_array( 'posts_orderby_request', array( $orderby, &$this ) );
$distinct = apply_filters_ref_array( 'posts_distinct_request', array( $distinct, &$this ) );
$fields = apply_filters_ref_array( 'posts_fields_request', array( $fields, &$this ) );
$limits = apply_filters_ref_array( 'post_limits_request', array( $limits, &$this ) );
$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) );
$this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) );
$this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) );
$split_the_query = apply_filters( 'split_the_query', $split_the_query, $this );
$this->request = apply_filters( 'posts_request_ids', $this->request, $this );
$this->posts = apply_filters_ref_array( 'posts_results', array( $this->posts, &$this ) );
$cjoin = apply_filters_ref_array( 'comment_feed_join', array( '', &$this ) );
$cwhere = apply_filters_ref_array( 'comment_feed_where', array( "WHERE comment_post_ID = '{$this->posts[0]->ID}' AND comment_approved = '1'", &$this ) );
$cgroupby = apply_filters_ref_array( 'comment_feed_groupby', array( '', &$this ) );
$this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) );
$this->posts = apply_filters_ref_array( 'the_posts', array( $this->posts, &$this ) );
$this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) );
$this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) );
do_action_ref_array( 'loop_start', array( &$this ) );
do_action_ref_array( 'loop_end', array( &$this ) );
do_action( 'comment_loop_start' );$pages = apply_filters( 'content_pagination', $pages, $post );
do_action_ref_array( 'the_post', array( &$post, &$this ) );

Возвращает

Объект/массив. Результат запроса в виде массива объектов записей.

Знакомство с WP_Query

WP_Query — это PHP класс, который позволяет получать посты из базы данных по самым разным критериям. Например, мы можем получить посты:

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

Рассмотрим простой запрос:

$query = new WP_Query( array( 'category_name' => 'news' ) );

Так, WordPress сделает запрос в базу данных, чтобы получить записи из категории «news».

Теперь, переменная $query содержит в себе объект с результатами запроса. Обработаем результат с помощью специальных методов:

while ( $query->have_posts() ) {
        $query->the_post();

        the_title(); // выведем заголовок поста}

С помощью have_posts() мы проверяем есть ли записи для вывода в объекте $query.the_post() готовит текущую в цикле запись к выводу, делая доступными привычные функции the_title()the_content() и другие.

WP_Query используется в WordPress всегда. Например, во время генерации любой страницы WP_Query создает глобальную переменную $wp_query где хранится информация о текущем запросе. На основе этой информации WP определяет на какой странице мы сейчас находимся (пост, архив, метка и т.д.). Также при построении базового цикла WordPress, данные берутся из переменной $wp_query и выводятся на экран через вспомогательные функции: the_permalink()the_content(). Также, $wp_query хранит и другие данные. На разных типах страниц данные разные. Посмотреть какие данные находятся в переменной $wp_query можно так:

global $wp_query;
print_r($wp_query);

Часто вы получаете информацию не работая напрямую с этим классом и глобальными переменными. Происходит это благодаря набору функций: условные теги, теги шаблона относящиеся к выводу данных внутри Цикла и ряда других функций.

Все условные теги (is_*()) обращаются к этому классу. Также, при создании циклаif( have_posts() )… все связанные с выводом данных функции работают с этим классом. Таким образом, ни одна генерация базовой страницы WP не проходит без использования класса WP_Query.

Если вы используете the_post() в запросе, вам нужно заканчивать цикл функциейwp_reset_postdata() (см. шаблоны использования).

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

$my_posts = new WP_Query;$myposts = $my_posts->query( array(
        'post_type' => 'page') );foreach( $myposts as $pst ){
        echo $pst->post_title;}

Шаблоны использования WP_Query

#1 Стандартный цикл:

// задаем нужные нам критерии выборки данных из БД$args = array(
        'posts_per_page' => 5,
        'orderby' => 'comment_count');

$query = new WP_Query( $args );

// Циклif ( $query->have_posts() ) {
        while ( $query->have_posts() ) {
                $query->the_post();
                echo '
  • ‘ . get_the_title() . ‘

‘; }} else { // Постов не найдено}/* Возвращаем оригинальные данные поста. Сбрасываем $post. */ wp_reset_postdata();

#2 Множественный цикл:

// Запрос к БД$the_query = new WP_Query( $args );

// Циклwhile ( $the_query->have_posts() ) {
        $the_query->the_post();
        echo '
  • ‘ . get_the_title() . ‘

‘;} /* Восстанавливаем оригинальные данные * Так как мы используем new WP_Query мы не влияем на * переменную $wp_query и нет необходимости сбрасывать запрос, * поэтому сбрасываем только данные поста. */ wp_reset_postdata(); /* Второй запрос (без глобальной переменной) */$query2 = new WP_Query( $args2 ); // 2-й Циклwhile( $query2->have_posts() ) { $query2->next_post(); echo ‘

  • ‘ . get_the_title( $query2->post->ID ) . ‘

‘;} // Восстанавливаем оригинальные данные поста wp_reset_postdata();

#3 Аналог get_posts():

$args = array(
        'post_type' => 'page');$query = new WP_Query;$my_posts = $query->query($args);

foreach( $my_posts as $my_post ){
        echo '

‘. $my_post->post_title .’

‘;}

При создании запросов WP_Query может получать предустановленные параметры, которые нужно учитывать. Например, запрос$query = new WP_Query( ‘post_type=func’ ); может вернуть только первые 10 записей типа func, а не все, как ожидается. Потому что предустановленный параметрposts_per_page=10, ограничивает количество получаемых записей до 10. Вот список параметров, которые могут быть предустановлены и которые могут мешать вашему запросу: post_typeposts_per_pageorderbyorderpost_statusoffset.

к меню ↑

Параметры Категорий (рубрик)

Получает посты относящиеся к определенным категориям.

cat(число/строка/массив)
ID категории. Можно указать несколько ID в строке через запятую или в массиве. Чтобы исключить рубрики укажите минус (-) перед ID категории — это исключит и все вложенные рубрики. Чтобы не исключить вложенные, используйте параметр category__not_in.
category_name(строка)
Имя категории. Используйте слаг (альтернативное имя), а не само название категории.
category__and(массив)
Получить посты, которые входят одновременно в несколько категорий.
category__in(массив)
Получить посты, которые входят в одну из указанных категорий.
category__not_in(массив)
Получить посты, которые не входят в указанную категорию.

Этот параметр не учитывает вложенные рубрики. Чтобы исключить рубрику и вложенные, укажите ID рубрик через запятую со знаком минус в параметре cat:-25,-32.

Посты из одной категории

Вывод постов из одной категории (записи из дочерних категорий так же будут выбраны):

$query = new WP_Query('cat=4');

вывод постов из одной категории по ярлыку (альтернативному названию категории):

$query = new WP_Query('category_name=staff');

Выведем посты только из категории 4 (дочерние категории не затрагиваются):

$query = new WP_Query( 'category__in=4' );

Посты из нескольких категорий

Вывод постов из категорий по ID категорий:

$query = new WP_Query('cat=2,6,17,38');

Выведем посты из категорий по слагу категорий:

$query = new WP_Query( 'category_name=staff,news' );

Исключим посты принадлежащие категориям

Выведем все посты, кроме постов из категорий 12,34,56:

$query = new WP_Query( 'cat=-12,-34,-56' );

Показать все посты, кроме тех, что принадлежать категории 3:

$query = new WP_Query('cat=-3');

Нескольких категорий одновременно

Показать посты, которые находятся сразу в двух категориях:

$query = new WP_Query( array( 'category__and' => array(2,6) ) );

Показать посты которые находятся хотя бы в одной из категорий (дочерние категории не будут учитываться):

$query = new WP_Query(array('category__in' => array(2,6)));

Можно исключить несколько категорий, таким образом:

$query = new WP_Query( array('category__not_in' => array(2,6)) );

к меню ↑

Параметры Меток

Получает посты относящиеся к определенным меткам.

tag(строка)
slug метки.
tag_id(число)
ID категорий.
tag__and(массив)
Посты одновременно из нескольких меток. Нужно указывать ID.
tag__in(массив)
Посты из хотя бы одной указанной метки. Нужно указывать ID.
tag__not_in(массив)
Посты не относящиеся к указанным меткам. Нужно указывать ID.
tag_slug__and(массив)
Тоже что и tag__and, только указываются альт. названия (slug) меток.
tag_slug__in(массив)
тоже что и tag__in, только указываются альт. названия меток.

Посты с одной меткой

Получить посты с меткой:

$query = new WP_Query('tag=cooking');

Указывать нужно альтернативное название метки.

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

$query = new WP_Query('tag=bread,baking');

Посты с несколькими метками

Получить посты имеющие любую из меток:

$query = new WP_Query( 'tag=bread,baking' );

Получить посты, имеющие сразу все указанные метки:

$query = new WP_Query('tag=bread+baking+recipe');

Получить посты, имеющие сразу две метки (37 и 47):

$query = new WP_Query( array('tag__and' => array(37,47)) );

Этот вариант более предпочтителен вышеприведенному из-за быстродействия.

Получить посты, имеющие хотя бы одно метку 37 или 47:

$query = new WP_Query( array('tag__in' => array(37,47)) );

Этот вариант предпочтительнее т.к. указываются сразу ID.

Получить посты, НЕ связанные с метками 37 или 47:

$query = new WP_Query(array('tag__not_in' => array(37,47)));

к меню ↑

Параметры Таксономий

Выводит посты связанные с определенной таксономией.

{tax}(строка)
Использовался в версиях ниже 3.1 для которого нужно было указывать «название термина» ( array(‘taxonomy_name’=>’categoriya’) ). Запрещен с версии 3.1.
tax_query(массив)
С версий 3.1 и выше используется аргумент tax_query, который имеет ряд вложенных аргументов, это:

  • relation (строка)
    Как выбирать записи из указанных таксономий. Указывается в первом массиве, а термины во вложенных. Может быть:
    AND — записи которые одновременно входят в указанные таксономии;
    OR — записи принадлежащие любой из указанных таксономий.
    Дальше указываются вложенные массивы, которые могут иметь следующие параметры:
    • taxonomy (строка) — Название таксономии
    • field (строка)
      Поле которое будет указывать в параметре terms. Может быть: idterm_id,name или slug.
      id/term_id — значит в terms указываем id терминов.
      slug — значит в terms указываем альтернативное название терминов.
      name — значит в terms указываем заголовок термина.
      По умолчанию: ‘term_id’
    • terms (число/строка/массив)
      Термины таксономии, из которых нужно вывести записи.
    • operator (строка)
      Оператор, указывающий как сравнивать указанные термины в параметре terms. Может быть:
      IN — записи из указанных терминов (по умолчанию);
      NOT IN — записи из всех терминов, кроме указанных;
      AND — записи одновременно принадлежащие всем указанным терминам;
      EXISTS — (с версии 4.1) существует;
      NOT EXISTS — (с версии 4.1) не существует.
      По умолчанию: ‘IN’
    • include_children (логический)
      Включать или нет посты из дочерних терминов (для древовидных таксономий). true -включить.
      По умолчанию: true

tax_query это массив, элементами которого являются другие массивы, в каждом из которых указывается таксономия, её термины и то как использовать эти термины. Оператор relation указывается в первом массиве tax_query и определяет как сравнивать вложенные массивы между собой. Такая конструкция позволяет создавать запрос одновременно к нескольким таксономиям.

#1 Вывод записей из одной таксономии

Выведем записи из раздела (термина) bob, который является элементом таксономии people:

$query = new WP_Query( array( 'people' => 'bob' ) );

#2 Выведем посты прикрепленные к термину bob из таксономии people:

$args = array(
        'post_type' => 'post',
        'people'    => 'bob');$query = new WP_Query( $args );

Сделаем тоже самое что и в примере выше, только с использованием аргумента tax_query:

$query = new WP_Query( array(
        'tax_query' => array(
                array(
                        'taxonomy' => 'people',
                        'field'    => 'slug',
                        'terms'    => 'bob'
                )
        )) );

#3 Вывод из нескольких таксономий

Выведем посты из нескольких произвольных таксономий:

$query = new WP_Query( array(
        'post_type' => 'post',
        'people'    => 'bob',
        'language'  => 'english') );

Аналог примера выше. Выведем записи, который одновременно относятся к нескольким произвольным таксономиям через tax_query:

$query = new WP_Query( array(
        'tax_query' => array(
                'relation' => 'AND',
                array(
                        'taxonomy' => 'movie_janner',
                        'field'    => 'slug',
                        'terms'    => array( 'action', 'comedy' ),
                ),
                array(
                        'taxonomy' => 'actor',
                        'field'    => 'id',
                        'terms'    => array( 103, 115, 206 ),
                        'operator' => 'NOT IN',
                )
        )) );

#4 Использование аргумента relation=OR

Выведем посты которые находятся в рубрике quotes или которые имеют формат quote (форматы введены в версии 3.1). Для этого используем аргумент relation:

$args = array(
        'post_type' => 'post',
        'tax_query' => array(
                'relation' => 'OR',
                array(
                        'taxonomy' => 'category',
                        'field' => 'slug',
                        'terms' => array( 'quotes' )
                ),
                array(
                        'taxonomy' => 'post_format',
                        'field' => 'slug',
                        'terms' => array( 'post-format-quote' )
                )
        ));$query = new WP_Query( $args );

#5 Многоуровневый сложный запрос с использование оператора relation=OR

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

Например, надо получить автомобили марки ford черного цвета или автомобили марки bmwбелого цвета:

$query = new WP_Query(
        array(
                'tax_query' => array(
                        'relation' => 'OR',
                        array(
                                'relation' => 'AND',
                                array(
                                        'taxonomy' => 'brand',
                                        'field'    => 'slug',
                                        'terms'    => array( 'ford' )
                                ),
                                array(
                                        'taxonomy' => 'color',
                                        'field'    => 'slug',
                                        'terms'    => array( 'black' )
                                )
                        ),
                        array(
                                'relation' => 'AND',
                                array(
                                        'taxonomy' => 'brand',
                                        'field'    => 'slug',
                                        'terms'    => array( 'bmw' )
                                ),
                                array(
                                        'taxonomy' => 'color',
                                        'field'    => 'slug',
                                        'terms'    => array( 'white' )

                                )
                        )
                )
        ));

$query = new WP_Query( $args );

Тут первый оператор relation=OR влиял бы на все вложенные массивы, если бы во вложенных массивах он не перебивался дополнительным оператором relation=AND

Использование get_posts()

#6 Выведем заголовки всех типов записей countries из всех подрубрик термина 62, который относится к таксономии country:

$args = array(
        'tax_query' => array(
                array(
                        'taxonomy' => 'country',
                        'field'    => 'id',
                        'terms'    => array( 62 )
                )
        ),
        'post_type' => 'countries',
        'posts_per_page' => -1);$posts = get_posts( $args );

foreach( $posts as $pst ){
        echo $pst->post_title .'
';}

#7 Выведем все записи произвольного типа (article) не относящиеся к указанным терминам (‘term-slug’, ‘term-slug-two’, ‘term-slug-three’) таксономии (artictag):

## получим все посты не относящиеся к указанным терминам
$post_type = ‘article’;$tax   = ‘artictag’;
$terms = array(‘term-slug’, ‘term-slug-two’, ‘term-slug-three’);

$psts  = get_posts( array(
‘posts_per_page’ => -1,
‘post_type’ => $post_type,
‘tax_query’ => array(
‘relation’ => ‘AND’,
array(
‘taxonomy’ => $tax,
‘terms’ => $terms,
‘field’ => ‘slug’,
‘operator’ => ‘NOT IN’,
)
),
» => »,) );

$i = 0;foreach( $psts as $pst ){
echo ++$i . ‘ к меню ↑

Параметры Авторов

Получает посты принадлежащие определенным авторам.

author(число)
ID автора.
author_name(число)
Ник автора. Нужно указывать значение поля user_nicename.
author__in(массив)
Массив ID авторов, записи которых нужно получить.
author__not_in(массив)
Массив ID авторов, записи которых нужно исключить.

#1 Выведем посты для одного автора

Посты по ID автора:

$query = new WP_Query( 'author=123' );

Посты по нику автора:

$query = new WP_Query( 'author_name=rami' );

#2 Выведем посты нескольких авторов сразу

Посты четырех авторов по ID:

$query = new WP_Query( 'author=2,6,17,38' );

#3 Исключим посты автора

Исключим посты автора 12 и покажем все посты, кроме его:

$query = new WP_Query( 'author=-12' );

#4 Еще пример

Показать все страницы автора 1 (author=1), отсортировать по заголовку (orderby=title) в алфавитном порядке (order=ASC) и не показывать прикрепленные посты вверху.

$query = new WP_Query('caller_get_posts=1&author=1&post_type=page&post_status=publish&orderby=title&order=ASC');

#5 Несколько авторов одновременно

Получим все записи авторов с ID 2 и 6:

$query = new WP_Query( array( 'author__in' => array( 2, 6 ) ) );

Получим записи всех авторов, кроме авторов с ID 2 и 6:

$query = new WP_Query( array( 'author__not_in' => array( 2, 6 ) ) );

к меню ↑

Параметры Постов и Страниц

Получает отдельные страницы или посты.

p(число)
ID поста который нужно получить (p=27).
name(строка)
Альт. название поста (name=o-saite).
page_id(число)
ID постоянной страницы, которую нужно получить (page_id=27)
pagename(строка)
Альт. название постоянной страницы (pagename=o-saite)
post_parent(число)
Вернет только дочерние страницы.
post_parent__in(массив)
Выберет посты родители которых указанны в массиве.
post_parent__not_in(массив)
Выберет посты родители которых не указанны в массиве.
post__in(массив)
Укажите через запятую ID постов, которые нужно получить (post__in=5,12,2,14,7). Внимание: если вы использует прилепленные посты, они будут включены, хотите вы того или нет. Чтобы это исправить, используйте параметр ignore_sticky_posts
post__not_in(массив)
Выведет все посты кроме указанных.

Посты/страницы по ID

Выведем пост по ID:

$query = new WP_Query('p=7');

Выведем страницу по ID:

$query = new WP_Query( 'page_id=7' );

Посты/страницы по Слагу

Выведем пост по Слагу:

$query = new WP_Query( 'name=about-my-life' );

Выведем страницу по Слагу:

$query = new WP_Query( 'pagename=contact' );

Дочерние посты/страницы

Выведем дочернюю страницу, используя слаг родительской и дочерней страницы разделенные слэшом: parent_slug/child_slug

$query = new WP_Query( 'pagename=contact_us/canada' );

Выведем дочерние страницы, используя ID родительской:

$query = new WP_Query( 'post_parent=93' );

Выведем страницы верхнего уровня, исключим все дочерние:

$query = new WP_Query( 'post_parent=0' );

Выведем посты родители которых указаны в массиве:

$query = new WP_Query( array( 'post_parent__in' => array( 2, 5, 12, 14, 20 ) ) );

Множественные выводы постов/страниц

Выведем только указанные посты:

$query = new WP_Query( 
        array( 'post_type' => 'page', 'post__in' => array( 2, 5, 12, 14, 20 ) ) 
);

Выведем все посты, кроме указанных:

$query = new WP_Query( array(
        'post_type' => 'post',
        'post__not_in' => array( 2, 5, 12, 14, 20 )) );

Заметка: вы не можете объединять post__in и post__not_in в одном запросе.

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

// не правильно$exclude_ids = '1,2,3';$query = new WP_Query( array( 'post__not_in' => array( $exclude_ids ) ) );

// Правильно$exclude_ids = array( 1, 2, 3 );$query = new WP_Query( array( 'post__not_in' => $exclude_ids ) );

к меню ↑

Параметры Произвольных полей (postmeta)

Основным параметром для работы с мета-данными в WP_Query является meta_query, который получает записи (посты) по существующим у них произвольным полям и их значениям. По принципу использования, meta_query похож на tax_query — массив, где каждый элемент в свою очередь является массивом с параметрами запроса, т.е. meta_query — это массив массивов:

$args = array(
        'meta_query' => array(
                'relation' => 'OR',
                array(
                        'key' => 'color',
                        'value' => 'blue'
                ),
                array(
                        'key' => 'price',
                        'value' => 20
                )
        ));

Такая конструкция позволяет использовать множественные запросы. Первый параметр relation во «внешнем» массиве описывает логическую связь между запросами. Он может принимать значения AND (используется по умолчанию. Совпадение со всеми запросами) или OR (совпадение с любым из запросов).

Старые переменные запроса мета-данных: meta_keymeta_value,meta_value_nummeta_compare по прежнему поддерживаются и могут быть использованы для простых запросов связанных с произвольными полями.

Список всех параметров связанных с мета-данными:

meta_key(строка)
Ключ(название) произвольного поля.
meta_value(строка)
Значение произвольного поля.
meta_value_num(число)
Значение произвольного поля, число.
meta_compare(строка)
Оператор для проверки значения произвольного поля. Может быть: =!=>>=<,<=LIKENOT LIKEINNOT INBETWEENNOT BETWEENEXISTS (с версии 3.5),NOT EXISTS (3.5), REGEXP (3.7), NOT REGEXP (3.7) и RLIKE (3.7);
По умолчанию ‘=’
meta_query(массив)
Массив параметров мета-данных определяющих вывод (этот параметр включает в себяmeta_keymeta_value и meta_compare и заменяет их). С версии 3.1.
В массиве можно указать следующие параметры:

  • relation (строка)
    Этот параметр указывается как строка в главном массиве meta_query и указывает как сравнивать между собой несколько массивов с параметрами запроса, указанных в этом главном массиве.
    Параметр может принимать два значение:
    OR — выбрать мета-поля подходящие хоты бы под один массив с параметрами запроса;
    AND (по умолчанию) — выбрать мета поля подходящие для всех массивов с параметрами запроса.
    • key (строка)
      Ключ поля.
    • value (строка/массив)
      Значение поля. Указывать не нужно, если при сравнении используется: ‘EXISTS’ или ‘NOT EXISTS’ (с версии 3.9).
    • compare (строка)
      Cравнение. может быть: =!=>>=<<=LIKENOT LIKEIN,NOT INBETWEENNOT BETWEENEXISTS (с версии 3.5), NOT EXISTS (3.5),REGEXP (3.7), NOT REGEXP (3.7) и RLIKE (3.7);
      По умолчанию ‘=’
    • type (строка)
      тип произвольного поля (если, например в поле указываются только числа то нужно использовать NUMERIC, чтобы числа не сравнивались как строки). Может быть:
      • NUMERIC — целые числа
      • DECIMAL — дробные числа
      • SIGNED — целые числа, положительные и отрицательные
      • UNSIGNED — целые числа, только положительные
      • CHAR — строка не чувствительна к регистру
      • BINARY — строка чувствительная к регистру
      • DATETIME — дата и время
      • DATE — только дата
      • TIME — только время
    • По умолчанию: CHAR.
  • Тип DATE работает при сравнении BETWEEN только если дата указывается в формате YYYY-MM-DD и сравнивается с аналогичным форматом.

Смотрите также отдельное описание класса мета запросов: WP_Meta_Query

Сортировка по произвольному полю

Для сортировки по полю, нужно указать ключ данных поля, и затем в параметре ‘orderby’ указать название этого ключа, например:

'meta_query' => array(
        'book_color' => array(
                'key'     => 'color',
                'value'   => 'blue',
                'compare' => 'NOT LIKE',
        ),),'orderby' => 'book_color','order'   => 'DESC',

Если произвольное поле указывается через параметр meta_key и meta_value, то для сортировки по этому полю в параметре orderby укажите значения: meta_value илиmeta_value_num (для чисел). См. ниже описание параметра orderby.

'meta_key=color&meta_value=blue&orderby=meta_value&order=ASC'

Базовые примеры (без meta_query)

#1 Посты с ключом произвольного поля color, не обращая внимание на значение этого поля.

$query = new WP_Query( 'meta_key=color' );

#2 Посты со значением произвольно поля blue, не обращая внимание на название ключа.

$query = new WP_Query( 'meta_value=blue' );

#3 Посты с ключом поля color и значением этого поля blue:

$query = new WP_Query( array( 'meta_key' => 'color', 'meta_value' => 'blue' ) );

#4 Посты у которых ключ равен color и значение поля не равно blue:

$query = new WP_Query( 
         array( 'meta_key' => 'color', 'meta_value' => 'blue', 'meta_compare' => '!=' ) 
);

#5 Продукты с ключом price и значение произвольно поля меньше или равно 22.

При использовании параметра «meta_value» значение 99 будет больше 100, так как эти значения распознаются как строки, а не числа. Для того чтобы числа понимались как числа нужно использовать параметр «meta_value_num»:

$query = new WP_Query( 
         array( 'meta_key' => 'price', 'meta_value_num' => '22', 'meta_compare' => '<=', 'post_type' => 'product' ) 
);

#6 Посты со значением произвольного поля равным 0, не важно какой ключ.

$query = new WP_Query( array ( 'meta_value' => '_wp_zero_value' ) );

Примеры с использованием meta_query

#1 Записи с одним произвольным полем

Выведем продукты (product) у которых ключ равен color и значение поля не равно blue:

$args = array(
        'post_type'  => 'product',
        'meta_query' => array(
                array(
                        'key'     => 'color',
                        'value'   => 'blue',
                        'compare' => 'NOT LIKE'
                )
        ));$query = new WP_Query( $args );

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

#2 Записи имеющие одновременно два произвольных поля

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

$args = array(
        'post_type'  => 'product',
        'meta_query' => array(
                array(
                        'key'     => 'color',
                        'value'   => 'blue',
                        'compare' => 'NOT LIKE'
                ),
                array(
                        'key'     => 'price',
                        'value'   => array( 20, 100 ),
                        'type'    => 'numeric',
                        'compare' => 'BETWEEN'
                )
        )
 );$query = new WP_Query( $args );

#3 Записи имеющие хотя бы одно поле

Выведем посты с ключом color и значением не (NOT LIKE) blue или (OR) посты с ключом price со значениями поля от 20 до 100:

$args = array(
        'post_type'    => 'product',
        'meta_query'   => array(
                'relation' => 'OR',
                array(
                        'key'     => 'color',
                        'value'   => 'blue',
                        'compare' => 'NOT LIKE'
                ),
                array(
                        'key'     => 'price',
                        'value'   => array( 20, 100 ),
                        'type'    => 'numeric',
                        'compare' => 'BETWEEN'
                )
        ));$query = new WP_Query( $args );

#4 Записи с двумя полями отсортированные по третьему полю

Предположим у нас есть тип записей toys — игрушки, а в произвольных полях мы указываем материал: твердая мягкая и вес игрушки в граммах: 100 300 500.

Получим мягкие игрушки вес которых от 200 до 500 грамм и отсортируем их по цене по убыванию:

$args = array(
        'post_type'  => 'toys',
        'meta_query' => array(
                array(
                        'key'   => 'type',
                        'value' => 'soft',
                ),
                array(
                        'key'     => 'weight',
                        'value'   => array( 200, 500 ),
                        'compare' => 'BETWEEN',
                        'type'    => 'NUMERIC',
                ),
        ),
        'meta_key' => 'price',
        'orderby'  => 'meta_value_num',
        'order'    => 'DESC');$query = new WP_Query( $args );

#5 Получим записи у которые есть произвольное поле

Этот пример показывает, как получить записи для которых установлены миниатюры (у которых есть произвольное поле _thumbnail_id):

$args = array(
        'posts_per_page' => 3,
        'post_type'  => 'post',
        'meta_query' => array(
                array(
                        'key' => '_thumbnail_id',
                        'compare' => 'EXISTS'
                )
        ));$query = new WP_Query( $args );

#6 Вложенные сложные запросы

С версии 4.1 можно создавать вложенные запросы. Например, выполним такое условие: нужно показать продукты оранжевого цвета (color=orange) ИЛИ маленькие (size=small) продукты красного цвета (color=red):

$args = array(
        'post_type'  => 'product',
        'meta_query' => array(
                'relation' => 'OR',
                array(
                        'key'     => 'color',
                        'value'   => 'orange',
                        'compare' => '=',
                ),
                array(
                                'relation' => 'AND',
                                array(
                                                'key'     => 'color',
                                                'value'   => 'red',
                                                'compare' => '=',
                                ),
                                array(
                                                'key'     => 'size',
                                                'value'   => 'small',
                                                'compare' => '=',
                                ),
                ),
        ),);$query = new WP_Query( $args );

#7 Сортировка по произвольному полю

С версии 4.2 массивам в meta_query можно указывать ключи, чтобы затем сортировать по этому ключу:

$args = array(
        'post_type'  => 'book',
        'meta_query' => array(
                'book_color' => array(
                        'key'     => 'color',
                        'value'   => 'blue',
                        'compare' => 'NOT LIKE',
                ),
        ),
        'orderby' => 'book_color',);$query = new WP_Query( $args );

к меню ↑

Параметры Типов постов

Показывает посты указанного типа.

post_type(строка/массив)
Записи какого типа нужно показывать. По умолчанию: post. Но если указан параметрtax_query, то по умолчанию ставиться any.

Может быть:

  • any — включает все типы, кроме revision и типов у которых указан параметрexclude_from_search=true.
  • attachment — по умолчанию WP_Query ставит статус 'post_status'=>'publish', а вложения имеют статус 'post_status'=>'inherit', поэтому чтобы вывести вложения нужно еще изменить параметр post_status на ‘inherit’ или ‘any’.
  • page — страница.
  • post — пост.
  • revision — ревизия.
  • custom_type — название (ярлык) произвольного типа записи.
  • array(‘post’,’page’) — сразу несколько типов в массиве.

По умолчанию: post

Посты по типу

Выведем только страницы:

$query = new WP_Query( 'post_type=page' );

Выведем все посты, кроме ревизий и типов постов у которых при регистрации параметр exclude_from_search выставлен в true:

$query = new WP_Query( 'post_type=any' );

Выведем 4 типа постов одновременно:

$query = new WP_Query( array(
        'post_type' => array( 'post', 'page', 'movie', 'book' )) );

к меню ↑

Параметры Статусов

Получает посты с указанным статусом.

post_status(строка/массив)
Статус поста. По умолчанию «publish», а если пользователь авторизован добавляется еще и private. Если запрос запущен из админ части, добавляются еще и защищенные типы статусов, это: ‘future’, ‘draft’ и ‘pending’. Все типы статусов:

  • publish — опубликованный пост;
  • pending — пост на модерации;
  • draft — черновик;
  • auto-draft — черновик, сохраненный самим WordPress (авто-сохранение);
  • future — запланированный пост;
  • private — личный пост;
  • inherit — ревизия;
  • trash — удаленный пост (в корзине). С версии 2.9;
  • any — все статусы, кроме типов постов с «exclude_from_search=true».

По умолчанию: ‘publish’

Посты по статусам

Получим только черновики:

$query = new WP_Query( 'post_status=draft' );

Получим посты с разными статусами:

$query = new WP_Query( 
         array( 'post_status' => array( 'pending', 'draft', 'future' ) ) 
);

Получим все виды вложений:

$query = new WP_Query( 
          array( 'post_status' => 'any', 'post_type' => 'attachment' ) 
);

к меню ↑

Параметры Даты (времени)

Выводит посты принадлежащие определенному периоду времени.

year(число)
4 цифры года (2013)
monthnum(число)
Номер месяцы (1 — 12)
w(число)
Неделя в году (с 0 до 53)
day(число)
День месяца (1 — 31)
hour(число)
Час (0 — 23)
minute(число)
Минута (0 — 60)
second(число)
Секунда (0 — 60)
m(число)
ГодМесяц (201306)
date_query(массив)
Работает на основе отдельного класса: WP_Date_Query.

  • column — поле в базе данных для запроса. По умолчанию post_date. Может быть: ‘post_date’, ‘post_date_gmt’, ‘post_modified’, ‘post_modified_gmt’, ‘comment_date’, ‘comment_date_gmt’.
  • compare — каким оператором производить сравнение. Может быть: =!=>>=,<<=INNOT INBETWEENNOT BETWEEN.
  • relation — оператор, если указаны несколько массивов с датами: AND (учитывать одновременно все указанные массивы) или OR (если есть совпадения хотя бы с одним указанным массивом). По умолчанию — OR
    • Эти параметры, которые должны использоваться во вложенном массиве. Они определяют сам запрос. Список параметров:
    • before (строка/массив) — строка или массив с датой «до»
    • after (строка/массив) — строка или массив с датой «после»
    • column (строка) — см. выше, только для конкретной даты. По умолчанию значение верхнего массива
    • compare (строка) — см. выше, только для конкретной даты. По умолчанию ‘=’
    • inclusive (логический) — аргументы before и after обрабатываются включительно, если true
    • year (число/массив) — год, например 2013
    • month (число/массив) — месяц, 1-12
    • week (число/массив) — неделя, 0-53
    • day (число/массив) — день, 1-31
    • dayofweek (число/массив) — день недели, 1-7
    • hour (число/массив) — час, 0-23
    • minute (число/массив) — минута, 0-60
    • second (число/массив) — секунда, 0-60

Общие примеры

#1. Получим посты за сегодня:

$today = getdate();$query = new WP_Query( 'year=' . $today["year"] . '&monthnum=' . $today["mon"] . '&day=' . $today["mday"] );

#2. Получим посты за последнюю неделю:

$week = date('W');$year = date('Y');$query = new WP_Query( 'year=' . $year . '&w=' . $week );

#3. Получим посты за 20 Декабря:

$query = new WP_Query( 'monthnum=12&day=20' );

Заметка: запросы выше возвращают посты за указанный период в истории: «Посты за Х месяц, Х день». Они не могут получать посты за произвольный промежуток времени по отношению к настоящему. Поэтому запросы типа «Посты за последние 30 дней» или «Посты за последний год» не возможны в базовом варианте, для таких запросов нужно использовать фильтр «posts_where». Примеры ниже показывают как это делать.

#4. Получим посты за промежуток времени с 1 марта по 15 марта 2010 года:

// Создадим новую функцию которая добавит условие where в запросfunction filter_where( $where = '' ) {
        // с 1 марта по 15 марта 2010 года
        $where .= " AND post_date >= '2010-03-01' AND post_date < '2010-03-16'";
        return $where;}

add_filter( 'posts_where', 'filter_where' );$query = new WP_Query( $query_string );
remove_filter( 'posts_where', 'filter_where' );

#5. Получим посты за последние 30 дней:

// Создадим новую функцию которая добавит условие where в запросfunction filter_where( $where = '' ) {
        // за последние 30 дней
        $where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
        return $where;}

add_filter( 'posts_where', 'filter_where' );$query = new WP_Query( $query_string );
remove_filter( 'posts_where', 'filter_where' );

#6. Получим посты за промежуток от 30 до 60 дней, до настоящего:

// Создадим новую функцию которая добавит условие where в запросfunction filter_where( $where = '' ) {
        // от 30 до 60 дней
        $where .= " AND post_date >= '" . date('Y-m-d', strtotime('-60 days')) . "'" . " AND post_date <= '" . date('Y-m-d', strtotime('-30 days')) . "'";
        return $where;}

add_filter( 'posts_where', 'filter_where' );$query = new WP_Query( $query_string );
remove_filter( 'posts_where', 'filter_where' );

Параметр "m" может быть установлен только в списке постов в админ-панели. Он полезен когда вы выбираете из выпадающего списка select где дата установлена как число YYYYmm.

Примеры с параметром date_query

#1. Получим посты между 9 и 17 часами:

$args = array(
        'date_query' => array(
                array(
                        'hour'      => 9,
                        'compare'   => '>=',
                ),
                array(
                        'hour'      => 17,
                        'compare'   => '<=', ), array( 'dayofweek' => array( 2, 6 ),
                        'compare'   => 'BETWEEN',
                ),
        ),
        'posts_per_page' => -1,);$query = new WP_Query( $args );

#2. Получим посты за промежуток времени: 1 января по 28 февраля:

$args = array(
        'date_query' => array(
                array(
                        'after'     => 'January 1st, 2013',
                        'before'    => array(
                                'year'  => 2013,
                                'month' => 2,
                                'day'   => 28,
                        ),
                        'inclusive' => true,
                ),
        ),
        'posts_per_page' => -1,);$query = new WP_Query( $args );

Даты можно указывать цифрами и строками, как видно из этого примера, потому что аргументы before и after обрабатываются функцией PHP strtotime(), а она понимает строки.

#3. Получим посты опубликованные год назад, но измененные в последний месяц:

$args = array(
        'date_query' => array(
                array(
                        'column' => 'post_date_gmt',
                        'before' => '1 year ago',
                ),
                array(
                        'column' => 'post_modified_gmt',
                        'after'  => '1 month ago',
                ),
        ),
        'posts_per_page' => -1,);$query = new WP_Query( $args );

#4. Получим посты за последние 2 недели, использовав строку '2 weeks ago':

$query = new WP_Query( array(
        'date_query' => array(
                'after' => '2 weeks ago',
        ),) );

#5. Получим записи за последние 2 месяца, опубликованные в будние дни:

$query = new WP_Query( array(
        'date_query' => array(
                after => '2 months ago',
                array(
                        'dayofweek' => array( 1, 5 ),
                        'compare' => 'BETWEEN',
                ),
        ),) );

Аргумент date_query работает и с классом WP_Comment_Query, поэтому его точно также можно использовать в функции: get_comments().

к меню ↑

Параметры Отступов

Можно установить отступ от первого поста в результатах запроса. Например, стандартно запрос возвращает 6 постов, а если в тот же запрос добавить параметр offset=1, то будут возвращены 5 постов (первый пост из запроса будет пропущен).

offset(число)
Сколько постов из результатов запроса пропустить.

Пример использования

Пропустим первый/один пост (offset=1) и вернем следующие 5:

$query = new WP_Query('posts_per_page=5&offset=1');

Параметры Сортировки и порядка

Сортирует и устанавливает направление сортировки.

order(строка)
Направление сортировки по параметру orderby, может быть:

  • ASC - по порядку, от меньшего к большему (1, 2, 3; a, b, c).
  • DESC - в обратном порядке, от большего к меньшему (3, 2, 1; c, b, a) .
orderby(строка)
Поля по которым можно сортировать посты. Может быть

  • none - не сортировать, выводить прям как находиться в БД. равносильно сортировке по ID. С версии 2.8.
  • ID - сортировка по ID.
  • author - сортировка по ID авторов.
  • title - сортировка по заголовку.
  • name - по названию поста (ярлык, слаг поста).
  • date - сортировка по дате публикации.
  • modified - сортировка по дате изменения.
  • type - по типу поста (post_type). С версии 4.0
  • parent - сортировка по значению поля parent.
  • rand - случайный порядок.
  • RAND(x) - в случайном порядке для числовых значений. Тут "x" - это целое число.
  • comment_count - сортировка по количеству комментариев. С версии 2.9.
  • menu_order - стандартно используется для страниц и вложений. Порядковый номер указывается на странице редактирования поста.
  • meta_value - по значения произвольного поля.

    Важно: параметр meta_key так же должен быть определен. Заметка: сортировка будет алфавитной и будет не логична, если значения
    произвольных полей числа (будет, например, так 1, 3, 34, 4, 56, 6 и т.д., а не 1, 3, 4, 6, 34, 56).

  • meta_value_num - сортировка по произвольным полям, значения которых являются числами. С версии 2.8.
  • ключ массива из meta_query - в этом случае сортировка будет по значению произвольного поля указанного в массиве meta_query.
  • post__in - учитывает порядок указанных ID в параметре post__in.
'orderby' = array()
С версии WordPress 4.0 в orderby можно указывать массив сочетающий в себе оба параметра: orderby и order. Сделано это для сортировки по нескольким колонкам одновременною Синтаксис такой:

'orderby' => array( 'title' => 'DESC', 'menu_order' => 'ASC' )

Примеры

#1 Сортировка по заголовку

$query = new WP_Query( array ( 'orderby' => 'title', 'order' => 'DESC' ) );

Отсортируем по порядку в меню, а затем по заголовку

$query = new WP_Query( array ( 'orderby' => 'menu_order title', 'order' => 'DESC' ) );

#2 Выведем один случайный пост:

$query = new WP_Query( array ( 'orderby' => 'rand', 'posts_per_page' => '1' ) );

#3 Отсортируем посты по количеству комментариев:

$query = new WP_Query( array( 'orderby' => 'comment_count' ) );

#4 Отсортируем продукты по цене (произвольное поле price):

$query = new WP_Query( 
         array ( 'post_type' => 'product', 'orderby' => 'meta_value', 'meta_key' => 'price' ) 
);

#5 Множественная сортировка

Выведем посты отсортированные по двум полям: 'title' и 'menu_order' (title первостепенен):

$query = new WP_Query( 
        array( 'post_type' => 'page', 'orderby' => 'title menu_order', 'order' => 'ASC' ) 
);

#6 Множественная сортировка с использованием массива (с версии 4.0)

Получим страницы отсортированные по заголовку (title) и номеру меню (menu_order) в разном порядке (ASC/DESC):

$query = new WP_Query( array( 'orderby' => array( 'title' => 'DESC', 'menu_order' => 'ASC' ) ) );

#7 Сортировка по 'meta_value' для нового типа поста (post_type)

Выведем посты типа 'my_custom_post_type' отсортированные по ключу произвольного поля "age" и отфильтрованные, чтобы показывались только посты со значением поля 3 и 4:

$args = array(
   'post_type' => 'my_custom_post_type',
   'meta_key' => 'age',
   'orderby' => 'meta_value_num',
   'order' => 'ASC',
   'meta_query' => array(
           array(
                   'key' => 'age',
                   'value' => array(3, 4),
                   'compare' => 'IN',
           )
   )
 );
 $query = new WP_Query($args);

к меню ↑

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

nopaging(логический)
Выключит пагинацию, выведет все посты на одной странице.
posts_per_page(число)
Количество постов на одной странице. Если выставить -1, то будут выведены все посты (без пагинации). С версии 2.1 заменяет параметр showposts. Установите параметр paged, если пагинация не работает, после использования этого параметра.Заметка: если запрос в feed части, WP перезаписывает этот параметр опцией posts_per_rss. Чтобы повлиять на вывод постов в фиде используйте фильтры post_limits илиpre_option_posts_per_rss.
posts_per_archive_page(число)
Количество постов для страниц архивов: для страниц, которые удовлетворяют условиямis_archive() или is_search(). Этот параметр перезаписывает параметры "posts_per_page" и "showposts".
offset(число)
Сколько постов пропустить сверху выборки (верхний отступ).
Внимание: Установка этого параметра переписывает/игнорирует параметр "paged" и ломает пагинацию (решение проблемы).
paged(число)
Номер страницы пагинации. Показывает посты, которые в обычном режиме должны были быть показаны на странице пагинации Х. Переписывает параметр posts_per_page
page(число)
Номер для статической домашней страницы. Показывает записи, которые в обычном режиме должны были быть показаны на странице пагинации Х главной статической странице (front page).
ignore_sticky_posts(логический)
Игнорировать прилепленные посты или нет (true/false). Доступен с версии 3.1. Заменяет параметр caller_get_posts. Заметка: прилепленные посты не будут показываться в начале списка, но они не исключаются и будут выводиться в обычном порядке.

Посты на странице

Выведем 3 поста на странице:

$query = new WP_Query( 'posts_per_page=3' );

Выведем все посты на странице:

$query = new WP_Query( 'posts_per_page=-1' );

Выведем все посты и отключим пагинацию:

$query = new WP_Query( 'nopaging=true' );

Отступы сверху

Выведем посты начиная с четвертого (пропустим первые 3):

$query = new WP_Query( 'offset=3' ) );

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

$query = new WP_Query( array( 'posts_per_page' => 5, 'offset' => 3 ) );

Посты со страницы пагинации Х

Покажем посты со страницы пагинации 6:

$query = new WP_Query( 'paged=6' );

Посты с текущей страницы

Покажем посты с текущей страницы пагинации. Полезно при построении произвольной пагинации:

$query = new WP_Query( array( 'paged' => get_query_var( 'paged' ) ) );

Выведем посты с текущей страницы и установим параметр paged в 1, когда переменная не определена на первой странице пагинации:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;$query = new WP_Query( array( 'paged' => $paged ) );

Заметка: Используйте get_query_var('page'); если нужно получить номер страницы пагинации для статической главной страницы сайта (is_front_page()). Переменная "page" раже содержит номер пагинации на отдельных страницах типа post, когда в контенте используется тег 

Страницы: 1 2

Страницы: 1 2