WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

WP_Query{} WP 1.5

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

Заметки по фильтрам

Можно использовать следующие фильтры для внедрения непосредственно в сам SQL запрос.

Важно: если указан параметр suppress_filters, то все эти хуки работать не будут!

Фильтры срабатывающие до установки запроса пагинации:
Фильтры срабатывающие после установки запроса пагинации:
  • posts_where_paged - изменяет SQL 'WHERE' во время пагинации
  • posts_groupby - изменяет SQL 'GROUP BY'
  • posts_join_paged - изменяет SQL 'JOIN' во время пагинации
  • posts_orderby - изменяет SQL 'ORDER BY'
  • posts_distinct - изменяет SQL 'DISTINCTROW'
  • post_limits - изменяет SQL 'LIMIT'
  • posts_fields - изменяет получаемые поля таблицы
  • posts_clauses - позволяет изменять все части одновременно, передает массив:

    Array (
    	[where]    =>  AND 1 = 1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
    	[groupby]  => wp_posts.ID
    	[join]     => INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
    	[orderby]  => wp_posts.post_date DESC
    	[distinct] => 
    	[fields]   => wp_posts.*
    	[limits]   => LIMIT 0, 10
    )
Является основой для: query_posts(), get_posts()
Возвращает

Объект WP_Query. В свойстве объекта ->posts находится массив объектов записей.

меню

Знакомство с 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 );

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

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

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

Код цикла может выглядеть следующим образом - это тоже самое что get_posts(), только без предустановленных параметров:

// создаем экземпляр
$my_posts = new WP_Query;

// делаем запрос
$myposts = $my_posts->query( array(
	'post_type' => 'page'
) );

// обрабатываем результат
foreach( $myposts as $pst ){
	echo esc_html( $pst->post_title );
}

Для лучшего понимания и визуального восприятия работы функций запроса, изучите картинку:

Как работают функции запросов в WordPress

Шаблоны использования 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 '<li>' . get_the_title() . '</li>';
	}
} else {
	// Постов не найдено
}
// Возвращаем оригинальные данные поста. Сбрасываем $post.
wp_reset_postdata();

#2 Стандартный цикл (Альтернатива)

<?php 
// запрос
$query = new WP_Query( $args ); ?>

<?php if ( $query->have_posts() ) : ?>

	<!-- пагинация -->

	<!-- цикл -->
	<?php while ( $query->have_posts() ) : $query->the_post(); ?>
		<h2><?php the_title(); ?></h2>
	<?php endwhile; ?>
	<!-- конец цикла -->

	<!-- пагинация -->

	<?php wp_reset_postdata(); ?>

<?php else : ?>
	<p><?php esc_html_e( 'Нет постов по вашим критериям.' ); ?></p>
<?php endif; ?>

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

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

// Цикл
while ( $query->have_posts() ) {
	$query->the_post();
	echo '<li>' . get_the_title() . '</li>';
}

/* 
Восстанавливаем оригинальные данные.
Мы используем new WP_Query, а значит мы не влияем на глобальную
переменную `$wp_query`, поэтому нет необходимости сбрасывать запрос и 
можно сбросить только данные поста.
*/
wp_reset_postdata();

// Второй запрос (без глобальной переменной)
$query2 = new WP_Query( $args2 );

// 2-й Цикл
while( $query2->have_posts() ) {
	$query2->next_post();
	echo '<li>' . get_the_title( $query2->post->ID ) . '</li>';
}

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

#4 Аналог get_posts()

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

foreach( $my_posts as $my_post ){
	echo '<p>'. $my_post->post_title .'</p>';
}

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

Список всех возможных параметров смотрите ниже, а также в коде метода WP_Query::parse_query().

меню

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

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

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

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

Этот параметр не учитывает вложенные рубрики. Чтобы исключить рубрику и вложенные рубрики, укажите ID рубрик через запятую со знаком минус в параметре cat: 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. Этот вариант предпочтительнее т.к. указываются сразу ID.

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

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

$query = new WP_Query(array( 'tag__not_in'=>array(37,47) ));
меню

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

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

{tax}(строка)
Нужно указывать имя таксономии и слаг термина: array('category'=>'wordpress'). Запрещен с версии 3.1.
tax_query(массив)

С WP 3.1. Нужно указать параметры запроса по таксономии. Может принимать ряд вложенных аргументов, это:

  • relation (строка)
    Как выбирать записи из указанных таксономий. Может быть:

    • AND - записи которые одновременно входят в указанные термины таксономии.
    • OR - записи принадлежащие любому из указанных терминов таксономии.

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

    • taxonomy (строка)
      Название таксономии.

    • field (строка)
      Поле которое будет указывать в параметре terms. Может быть:

      • id или term_id - в terms указываем id терминов.
      • name - в terms указываем заголовок термина.
      • slug - в terms указываем ярлык термина.

        По умолчанию: 'term_id'

    • terms (число/строка/массив)
      Термины таксономии, из которых нужно вывести записи.

    • operator (строка)
      Оператор, указывающий как сравнивать указанные термины в параметре terms. Может быть:

      • IN - записи из указанных терминов (по умолчанию).
      • NOT IN - записи из всех терминов, кроме указанных.
      • AND - записи одновременно принадлежащие всем указанным терминам.
      • EXISTS - записи из таксономии (у которых есть любой термин таксономии). В этом случае параметр terms указывать не надо. С версии 4.1.
      • NOT EXISTS - записи НЕ из таксономии (у которых нет ни одного термина таксономии). В этом случае параметр terms указывать не надо. С версии 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( [
	'tax_query' => [
		'relation' => 'AND',
		[
			'taxonomy' => 'movie_janner',
			'field'    => 'slug',
			'terms'    => array( 'action', 'comedy' ),
		],
		[
			'taxonomy' => 'actor',
			'field'    => 'id',
			'terms'    => array( 103, 115, 206 ),
			'operator' => 'NOT IN',
		]
	]
] );

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

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

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

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

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

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

В этом примере первый оператор relation=OR влияет на первые дочерние вложенные массивы. А оператор relation=AND во вложенных массивах влияет на массивы вложенных массивов.

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

				]
			]
		]
	]
);

$query = new WP_Query( $args );

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

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

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

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

#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 . ' <a href="'. get_permalink( $pst->ID ) .'">'. $pst->post_title .'</a><br>';
}

#8 Получим все записи типа func, которых нет в таксономии func_cat

Т.е. получим записи типа func, у которых нет ни одного термина из таксономии func_cat. Для этого используем параметр 'operator=NOT EXISTS'.

$posts = get_posts( [
	'tax_query' => [
		[
			'taxonomy' => 'func_cat',
			'operator' => 'NOT EXISTS',
		]
	],
	'post_type' => 'func',
	'posts_per_page' => -1
] );

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

#9 Выборка записей из таксономии и сортировка по метаполю

Получим записи типа 'func', которые находятся в любом элементе таксономии 'tplcat' и отсортируем эти записи по числовому метаполю 'views_prev_month'.

$query = new WP_Query( [
	'post_type'      => 'func',
	'posts_per_page' => -1,
	'tax_query' => [
		[
			'taxonomy' => 'tplcat',
			'operator' => 'EXISTS',
		]
	],
	'meta_key' => 'views_prev_month',
	'orderby'  => [ 'meta_value_num'=>'DESC' ],
] );
меню

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

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

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(строка)
post_name (слаг) записи (поста). Пример: name=o-saite.
title(строка)
Заголовок записи (поста). Пример: name=О сайте. С версии 4.4.
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(массив)
Выберет все посты кроме указанных.
post_name__in(массив)
Выберет указанные посты. Указывать нужно post_name (slug) через запятую или в массиве. С версии 4.4.

Посты/страницы по 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&post_type=page' );

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

$query = new WP_Query( 'post_parent=93&post_type=page' );

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

$query = new WP_Query( 'post_parent=0&post_type=page' );

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

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

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

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

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

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

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

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

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

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

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

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

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

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' )
) );
меню

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

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

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

$args = [
	'meta_query' => [
		'relation' => 'OR',
		[
			'key' => 'color',
			'value' => 'blue'
		],
		[
			'key' => 'price',
			'value' => 20
		]
	]
];

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

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

meta_key(строка)
Ключ(название) произвольного поля.
meta_value(строка)
Значение произвольного поля.
meta_value_num(число)
Значение произвольного поля, число.
meta_compare_key(строка) (с версии 5.1)
Оператор указывающий то, как нужно искать указанный в meta_key ключ. Может быть: = или LIKE.
По умолчанию: '='
meta_compare(строка)
Оператор для проверки значения произвольного поля. Может быть: =, !=, >, >=, <, <=, LIKE, NOT LIKE, IN, NOT IN, BETWEEN, NOT BETWEEN, EXISTS (с версии 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_key (строка) (с версии 5.1)
      Как сравнивать указанное в key значение. Может быть: = или LIKE.
      По умолчанию: '='

    • compare (строка)
      Как сравнивать указанное в value значение. Может быть: 

      • = - равно.
      • != - не равно.
      • > - больше.
      • >= - больше или равно.
      • < - меньше.
      • <= - меньше или равно.
      • LIKE - указанная в value подстрока имеется в строке. Как '%значение%' в sql запросе.
      • NOT LIKE - тоже что LIKE только наоборот.
      • IN - в value указываются несколько значений в массиве и поиск идет хотя бы по одному из значений.
      • NOT IN - любое значение, кроме тех что указанны в виде массива в value.
      • BETWEEN - в value указываются 2 значения в массиве: большее и меньшее и поиск идет между этих значений. , например: 'value' => array(5, 25) - от 5 до 25 (включительно).
      • NOT BETWEEN - любое значение, за пределами диапазона указанного в value, например: 'value' => array(5, 25) - меньше 5 и больше 25.
      • EXISTS - выведет всё где существует указанный в 'key' ключ. 'value' не указывается в этом случае. (с версии 3.5)
      • NOT EXISTS - выведет всё где указанный в 'key' ключ не существует. 'value' не указывается в этом случае. (с версии 3.5)
      • REGEXP - в value указывается регулярное выражение для поиска, например: 'value' => '^bar', (найдет строку: 'bar is'). (с версии 3.7)
      • NOT REGEXP - в value указывается регулярное выражение для поиска, найдет все что не входит в это выражение. (с версии 3.7)
      • RLIKE - синоним REGEXP. (с версии 3.7)

      По умолчанию 'IN', когда value массив, '=' в других случаях.

    • type (строка)
      тип произвольного поля (если, например в поле указываются только числа то нужно использовать NUMERIC, чтобы числа не сравнивались как строки).

      Указанный тут тип напрямую передается в mysql функцию CAST().

      Может быть:

      • NUMERIC - целые числа. Можно указать точность NUMERIC(p,s).
      • DECIMAL - дробные числа. Можно указать точность DECIMAL(p,s). Например: DECIMAL(5,2) - число с макс 5 цифрами всего (3 до разделителя) и 2 цифры после разделителя.
      • SIGNED - целые числа, положительные и отрицательные
      • UNSIGNED - целые числа, только положительные
      • CHAR - строка не чувствительна к регистру
      • BINARY - строка чувствительная к регистру
      • DATETIME - дата и время
      • DATE - только дата
      • TIME - только время

      Если указать любое другое значение (или вообще не указать значение), то оно превратиться в CHAR.

      По умолчанию: 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 );
меню

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

Выбирает вложения с указанным MIME типом. Список MIME типов смотрите в описании wp_get_mime_types().

post_mime_type(строка/массив)

Миме тип записи. Используется только для вложений - записей с типом 'attachment'.

Этот параметр будет работать только когда параметр post_type = attachment и post_status = inherit. Т.е. MIME-тип может быть только у вложений.

Получим только картинки любого типа

$query = new WP_Query( array(
	'post_mime_type' => 'image',
	'post_type'      => 'attachment',
	'post_status'    => 'inherit',
) );

Получим только картинки gif типа

$query = new WP_Query( array(
	'post_mime_type' => 'image/gif',
	'post_type'      => 'attachment',
	'post_status'    => 'inherit',
) );

Получим все типы вложений, кроме картинок

$query = new WP_Query( array(
	'post_mime_type' => array('application','text','video','audio'),
	'post_type'      => 'attachment',
	'post_status'    => 'inherit',
) );
меню

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

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

post_status(строка/массив)

Статус поста.

По умолчанию publish, а если пользователь авторизован добавляется еще и private. Если запрос запущен из админ части, добавляются еще и защищенные типы статусов: future, draft и pending. Все типы статусов:

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

По умолчанию: '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, compare, relation для основного массива работают как параметры по умолчанию для вложенных массивов (если они есть).

Возможные форматы дат смотрите в документации PHP.

  • column — поле в базе данных для запроса. Может быть:
    post_date
    post_date_gmt
    post_modified
    post_modified_gmt
    comment_date
    comment_date_gmt
    user_registered
    По умолчанию: 'post_date'

  • compare — Оператор сравнения для всех вложенных массивов по умолчанию. Может быть: Может быть: =, !=, >, >=, <, <=, IN, NOT IN, BETWEEN, NOT BETWEEN.
    По умолчанию: '='

  • relation — оператор, если указаны несколько массивов с датами:
    AND (учитывать одновременно все указанные массивы).
    OR (если есть совпадения хотя бы с одним указанным массивом).
    По умолчанию - OR

    Параметры ниже должны использоваться во вложенных массивах. Они определяют запрос для отдельной даты.

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

    • before (строка/массив) — Дата записи "до" которой будут получены. Принимает строку которую поймет функция strtotime(): все возможные форматы. Или можно передать массив с индексами: year, month, day: array('year'=>'2015', 'month'=>'5', 'day'=>'28' )
      Относительно текущего времени сайта (не UTC).

    • after (строка/массив) — Дата записи "после" которой будут получены. Принимает строку которую поймет функция strtotime(): все возможные форматы. Или можно передать массив с индексами: year, month, day: array('year' => '2015', 'month' => '5', 'day' => '28' )
      Относительно текущего времени сайта (не UTC).

    • column (строка) — см. выше, только для конкретной даты. По умолчанию: значение верхнего массива.

    • compare (строка) — см. выше, только для конкретной даты. По умолчанию '='.

    • inclusive (логический) — аргументы before и after обрабатываются включительно, если true. По умолчанию: false.

    • year (число/массив) — год, например 2013
    • dayofyear (число/массив) — номер дня в году, 1-366.
    • month (число/массив) — месяц, 1-12
    • week (число/массив) — неделя, 0-53
    • day (число/массив) — день, 1-31
    • dayofweek (число/массив) — день недели, 1-7, где 1 - воскресенье
    • dayofweek_iso (число/массив) — день недели, 1-7, где 1 - понедельник
    • hour (число/массив) — час, 0-23
    • minute (число/массив) — минута, 0-60
    • second (число/массив) — секунда, 0-60

    В параметрах: year, month, week, dayofyear, day, dayofweek, dayofweek_iso, hour, minute, second можно указать несколько значений, в виде массива, если параметр compare соответствует.

#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' );

#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' );

Запросы выше возвращают посты за указанный период в истории: "Посты за Х месяц, Х день". Они не могут получать посты за произвольный промежуток времени по отношению к настоящему. Поэтому запросы типа "Посты за последние 30 дней" или "Посты за последний год" не возможны в базовом варианте, для таких запросов нужно использовать фильтр "posts_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 февраля:

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

$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 );

#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');

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

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

Параметры сортировки не будут работать, если указать параметр fields = ids, потому что в этом случае, в запросе не будет полей по которым можно отсортировать результат.

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.
  • relevance — по условию поиска (параметр s). Сортировка идет в следующем порядке: 1) соответствует ли все предложение. 2) все условия поиска в заголовке записи. 3) какие-либо слова из запроса поиска в заголовке записи. 4) полное предложение найдено в контенте записи.
  • 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. Параметр order игнорируется.
  • post_name__in — учитывает порядок указанных имен в параметре post_name__in. Параметр order игнорируется.
  • post_parent__in — учитывает порядок указанных ID в параметре post_parent__in. Параметр order игнорируется.

С версии 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);

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

Чтобы отсортировать результат по двум разным метаполям, например, сначала по city , а затем по state, нужно указать ключи для массивов в массиве meta_query и затем использовать эти ключи в параметре orderby:

$query = new WP_Query( [
	'meta_query' => [
		'relation'     => 'AND',
		'state_clause' => [
			'key'   => 'state',
			'value' => 'Wisconsin',
		],
		'city_clause' => [
			'key'     => 'city',
			'compare' => 'EXISTS',
		], 
	],
	'orderby' => [
		'city_clause'  => 'ASC',
		'state_clause' => 'DESC',
	],
] );
меню

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

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.

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

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

Получим 3 поста:

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

Получим все посты:

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

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

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

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

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

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

Получим 5 постов, которые идут за тремя первыми постами:

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

#3 Записи со страницы пагинации 6

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

#4 Записи с текущей страницы

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

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

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

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

Используйте get_query_var('page') если нужно получить номер страницы пагинации статической главной страницы сайта — is_front_page(). Переменная page в этом случае, содержит номер пагинации на страницах типа post, когда в контенте используется тег разбиения контента на страницы <!--nextpage-->.

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

$paged = get_query_var('page') ?: 1;
$query = new WP_Query( [ 'paged' => $paged ] );

#5 Прилепленные записи (посты)

# Все прилепленные записи
$sticky = get_option( 'sticky_posts' );
$query = new WP_Query( [ 'post__in' => $sticky ] );
# Только первый прилепленный пост
$sticky = get_option( 'sticky_posts' );
$query = new WP_Query( 'p=' . $sticky[0] );
# Первый прилепленный пост, если такого поста нет, то последний опубликованный
$args = array(
	'posts_per_page'      => 1,
	'post__in'            => get_option( 'sticky_posts' ),
	'ignore_sticky_posts' => 1
);
$query = new WP_Query( $args );
# Первый прилепленный пост, если такого поста нет, то ничего не выводим
$sticky = get_option( 'sticky_posts' );

if ( ! empty($sticky[0]) ) {

	$query = new WP_Query( array(
		'posts_per_page'      => 1,
		'post__in'            => $sticky,
		'ignore_sticky_posts' => 1
	) );

	// формируем вывод...
}
# 5 последних прилепленных записей
$sticky = get_option( 'sticky_posts' ); // все Sticky записи

rsort( $sticky ); // отсортируем - новые вверху

$sticky = array_slice( $sticky, 0, 5 ); // получим первые 5

$query = new WP_Query( [ 'post__in'=>$sticky, 'ignore_sticky_posts'=>1 ] );

#6 Скрытие прилепленных постов

Исключим все прилепленные посты из запроса:

$query = new WP_Query( [ 'post__not_in' => get_option( 'sticky_posts' ) ] );

Исключим прилепленные посты из категории. Вернет все посты рубрики, но прилепленные посты не будут сверху, они будут выводится как обычные посты (по дате):

$query = new WP_Query( [ 'ignore_sticky_posts' => 1, 'posts_per_page' => 3, 'cat' => 6 ] );

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

$paged  = get_query_var( 'paged' ) ?: 1;
$sticky = get_option( 'sticky_posts' );
$query  = new WP_Query( array(
	'cat'                 => 3,
	'ignore_sticky_posts' => 1,
	'post__not_in'        => $sticky,
	'paged'               => $paged
) );
меню

Параметры Комментариев

В объект WP_Query добавляются данные комментариев записи, если это отдельная запись. В параметрах ниже, указывается как нужно получать комментарии в таких случаях.

comment_status(строка)
Статус комментария.
ping_status(число)
Статус пинга.
comments_per_page(число)
Число комментариев для получения на отдельной странице комментариев. По умолчанию опция: comments_per_page.
comment_count(число/массив)

Количество комментариев, которое должен иметь пост. С версии 4.9.

  • Если указать число, получит посты с указанным числом комментариев (оператор поиска =).
  • Массив позволяет указать вариант сравнения числа комментариев. В массиве можно указать параметры:
    • value (число) - количество комментариев для сравнения.
    • compare (строка) - как сравнивать кол-во комментов. Может быть: =, !=, >, >=, <, <=. По умолчанию: =.
меню

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

s(строка)
Поисковая фраза.
exact(логический)
true - искать по точной фразе указанной в параметре s - без добавления % на концы поисковой фразы в SQL запрос.
По умолчанию: false
sentence(true/false)
true — искать по полной поисковой фразе, прям как есть.
false — поисковая фраза делится на слова и поиск происходит по словам из поисковой фразы.
По умолчанию: false

Посты найденные по поисковой фразе:

$query = new WP_Query( 's=keyword' );

Параметры Возвращаемых полей

Устанавливает какие данные должен возвращать запрос.

fields(строка/массив)

Какие данные возвращать. По умолчанию возвращаются все.

  • ids - вернет массив с ID постов.
  • id=>parent - вернет ассоциативный массив [ parent => ID, … ].
  • Вставка любых других параметров, вернет все поля (по умолчанию) - массив объектов постов.
no_found_rows(логический)
true - не подсчитывать количество найденных строк. В некоторых случаях может ускорить запрос.
По умолчанию: false
меню

Параметры Кэширования

Не добавляет данные в кэш при выполнении запросов.

cache_results(true/false)
Кэшировать ли информацию о посте.
По умолчанию: true
update_post_meta_cache(true/false)
Кэшировать ли информацию о мета данных поста.
По умолчанию: true
update_post_term_cache(true/false)
Кэшировать ли информацию о привязке поста к терминам и таксономиям.
По умолчанию: true
lazy_load_term_meta(true/false)
Следует ли «лениво» загружать метаданные термина.
false — отключит отложенную загрузку метаданных термина и каждый вызов get_term_meta() будет обращаться в базу данных.
По умолчанию: значение $update_post_term_cache

#1 Выведем 50 постов, но не будет добавлять информацию о постах в кэш:

$query = new WP_Query( array( 'posts_per_page' => 50, 'cache_results' => false ) );

#2 Выведем 50 постов, но не будем добавлять мета данные поста в кэш

$query = new WP_Query( array( 'posts_per_page' => 50, 'update_post_meta_cache' => false ) );

#3 Выведем 50 постов, но не будем добавлять в кэш информацию о терминах постов

$query = new WP_Query( array( 'posts_per_page' => 50, 'update_post_term_cache' => false ) );

Обычно эти функции использовать не нужно - кэш необходим! Однако, такой подход может пригодится в ряде случаев. Например, если нам нужно получить список заголовков постов и не нужна никакая другая информация о постах: ни о таксономиях ни о мета данных. Не загружая эту информацию мы может сохранить время на ненужных SQL запросах.

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

меню

Параметры Фильтров (хуков)

suppress_filters(true/false)

Следует ли отключать работу некоторых фильтров (хуков) в классе WP_Query. Включение этого параметра отменяет все фильтры изменения SQL запроса, такого типа posts_* или comment_feed_*.

true — отключить обработку следующих хуков:

posts_search
posts_search_orderby

posts_where
posts_join

posts_where_paged
posts_groupby
posts_join_paged
posts_orderby
posts_distinct
post_limits
posts_fields
posts_clauses

posts_where_request
posts_groupby_request
posts_join_request
posts_orderby_request
posts_distinct_request
posts_fields_request
post_limits_request
posts_clauses_request

posts_request
posts_results
the_posts

comment_feed_join
comment_feed_where
comment_feed_groupby
comment_feed_orderby
comment_feed_limits

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

меню

Параметры Доступа

Показывает посты если пользователь имеет достаточные права.

perm(строка)
Доступ пользователя.

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

$query = new WP_Query( 
	  array( 'post_status' => array( 'publish', 'private' ), 'perm' => 'readable' ) 
);

Комбинирование параметров

#1. Комбинирование в строке

Вы наверняка заметили, что параметры соединяются между собой символом амперсанд - &, именно этим символом параметры комбинируются (объединяются).

Получим посты из категории 3 за 2004 год:

$query = new WP_Query( 'cat=3&year=2004' );

Получим посты из категории 1, имеющие метку apples:

$query = new WP_Query( 'cat=1&tag=apples' );

#2. Комбинирование с переменными

Посты из категории 13 за текущий месяц на главной странице блога:

if ( is_home() ) {
	$query = new WP_Query( $query_string . '&cat=13&monthnum=' . date('n',current_time('timestamp') ) );
}

#3. Комбинирование массивом

Вернет только 2 поста, из категории 1 и 3, отсортированные в обратном порядке по заголовку:

$query = new WP_Query( array(
   'category__and'  => array(1,3),
   'posts_per_page' => 2,
   'orderby'        => 'title',
   'order'          => 'DESC',
));

Примеры

#1. На главной, исключим посты из рубрики 3

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

<?php
if ( is_home() ) {
	query_posts( 'cat=-3' );
}
?>

#1.2. Можно добавить еще несколько категорий к исключению:

<?php
if ( is_home() ) {
	$query = new WP_Query( "cat=-1,-2,-3" );
}
?>

#2. Получим определенный пост (пост с ID = 5):

<?php
// retrieve one post with an ID of 5
$query = new WP_Query('p=5');
?>

#3. Если нужно использовать функцию "читать дальше" (read more) с новым запросом, то нужно переключить глобальную переменную $more на 0:

<?php
// retrieve one post with an ID of 5
$query = new WP_Query('p=5');

global $more;
// set $more to 0 in order to only get the first part of the post
$more = 0; 

// the Loop
while (have_posts()) : the_post();
  // the content of the post
  the_content('Read the full post »');
endwhile;
?>

#4. Получаем определенную страницу (страницу 7):

<?php
$query = new WP_Query('page_id=7');      // получит только страницу с ID 7
?>

или

<?php
$query = new WP_Query('pagename=o-saite'); // получит только страницу "o-saite"
?>

#4.1. Для дочерних страниц нужно указывать имя родительской страницы и самой дочерней страницы. Имена разделяются слэшем (/). Пример:

<?php
$query = new WP_Query('pagename=o-saite/avtori'); // получит страницу "avtori", которая является дочерней к "o-saite"
?>

Вставка переменных в параметры запроса

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

#1. Сборка запроса с использованием одинарных кавычек ' ':
<?php
$category_var = $cat; // задаем переменной $category_var ID текущей категории
$query = 'cat=' . $category_var . '&orderby=date&order=ASC'; // собираем запрос
$query = new WP_Query($query); // запускаем запрос к БД
?>
#2. Сборка запроса с использованием двойных кавычек " "

Переменные внутри двойных кавычек интерпретируются PHP как переменные, а не как простой текст:

<?php
$current_month = date('m');
$current_year = date('Y');

$query = new WP_Query("cat=22&year=$current_year&monthnum=$current_month&order=ASC");
?>
<!-- здесь идет Цикл WordPress -->
#3. Использование глобальной переменной $query_string

Которая содержит в себе базовый запрос для функции query_posts. Если нам нужно не нарушать стандартный вывод постов WordPress (например, на странице категорий), но при этом убрать пагинацию (вывести все посты на одной странице), то мы может дополнить базовый запрос функции query_posts, параметром posts_per_page=-1:

<?php
global $wp_query;
$wp_query = new WP_Query( $query_string . '&posts_per_page=-1');
while( have_posts() ){
	the_post();
	// здесь идет Цикл WordPress
}

wp_reset_query(); // сброс глобальной $wp_query
?>

Можно измерить значение posts_per_page на конкретное число необходимых нам постов на одной странице. Например, posts_per_page=10 выведет только 10 постов, а если при этом в конце цикла поставить тег шаблона posts_nav_link(), то под циклом появится ссылка для перехода к следующим 10-ти постам (ссылка пагинации).

#4. Параметры также можно передать в виде массива

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

$query = new WP_Query(array(
	'cat'      => 22,
	'year'     => $current_year,
	'monthnum' => $current_month,
	'order'    => 'ASC',
));

Как видите тут можно поставить каждую переменную на отдельную строку, а это более понятно и читаемо.

Добавление параметров в запрос

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

функция query_posts() полностью переписывает запрос, если например, мы напишем query_posts('cat=1'), то другие параметры запроса, которые используются для текущей страницы (например, сортировка, пагинация и т.д.), будут потеряны и будут выведены посты категории 1 с остальными параметрами по умолчанию. Чтобы сохранить базовые параметры запроса и дополнить/заменить их своими нужно использовать PHP функцию array_merge() (объединяет 2 массива в один):

global $wp_query;
query_posts(
	array_merge(
		array('cat' => 1), // это параметр который добавили мы
		$wp_query->query   // это массив базового запроса текущей страницы
	)
);

Этот пример по сути тоже самое что и пример 3 (Использование глобальной переменной $query_string), только с использованием массивов.

меню

Методы и свойства класса

Свойства класса WP_Query

$query
Хранит строку запроса.
$query_vars
Ассоциативные массив с данными запроса.
$tax_query
Запрос для таксономии, объект который передается в get_tax_sql().
$meta_query
Запрос для метаполей.
$date_query
Запрос для дат.
$queried_object
Применяется в запросах типа: рубрика, автор, пост или страница. Содержит информацию о категории, авторе, посте или странице.
$queried_object_id
Если запрос относится к рубрике, автору, посте или странице, содержит соответствующий ID.
$request
Полный SQL запрос, который был построен на основе переданных параметров запроса.
$posts
Заполняется данными постов полученными из Базы Данных.
$post_count
Количество постов выводимых на странице.
$current_post
Доступно во время цикла. Индекс текущего поста, которые выводиться.
$in_the_loop
Логическая переменная. Определяет начат ли цикл и находится ли вызываемый объект в цикле.
$post
Доступно во время цикла. Пост который выводится в текущий момент.
$comments
Список комментариев для текущего поста.
$comment_count
Количество комментариев для постов.
$current_comment
Текущий комментарий в цикле комментариев.
$comment
ID текущего комментария.
$found_posts
Количество всех найденных постов.
$max_num_pages
Количество страниц пагинации: $found_posts / $posts_per_page
$is_single, $is_page, $is_archive, $is_preview, $is_date, $is_year, $is_month, $is_time, $is_author, $is_category, $is_tag, $is_tax, $is_search, $is_feed, $is_comment_feed, $is_trackback, $is_home, $is_404, $is_comments_popup, $is_admin, $is_attachment, $is_singular, $is_robots, $is_posts_page, $is_paged
Логические значения. Определяют к какому из типа страницы относится текущий запрос.
$stopwords
Кэшированный список стопслов для поиска.

Методы класса WP_Query

Амперсанд (&) перед методом, вызывает его как ссылку.

init()
Активирует объект, выставляет все значение свойств в null, 0 или false.
parse_query( $query )
Получает параметры запроса, анализирует их и выставляет базовые свойства класса: $posts, $post_count, $post и $current_post.
parse_query_vars()
Анализирует старый запрос заново.
get( $query_var )
Получает переменную запроса по имени.
set( $query_var, $value )
Устанавливает переменную запроса. Указываются: название переменной и её значение.
&get_posts()
Получает требуемые посты из БД. Также заполняет свойства $posts и $post_count.
next_post()
Используется во время цикла. Переходит к следующему посту в массиве $posts. Устанавливает $current_post и $post. Метод не устанавливает глобальную переменную $post, а влияет на переменную внутри класса. Возвращает данные текущего поста (объект).
the_post()
Используется во время цикла. Переходит к следующему посту и меняет глобальную переменную $post.
have_posts()
Используется прям перед циклом. Проверяет есть ли посты для вывода.
rewind_posts()
Сбрасывает переменные $current_post и $post.
&query( $query )
Вызывает методы: parse_query() и get_posts(). Возвращает результат get_posts().
get_queried_object()
Заполняет переменную $queried_object, если она еще не заполнена и возвращает её.
get_queried_object_id()
Заполняет переменную $queried_object_id , если она еще не заполнена и возвращает её.
__construct($query = '')
Конструктор класса. Если переданы данные запроса, вызывает метод query() и передает ему данные.

  1. init_query_flags()
  2. init()
  3. parse_query_vars()
  4. fill_query_vars( $array )
  5. parse_query( $query = '' )
  6. parse_tax_query( &$q )
  7. parse_search( &$q )
  8. parse_search_terms( $terms )
  9. get_search_stopwords()
  10. parse_search_order( &$q )
  11. parse_orderby( $orderby )
  12. parse_order( $order )
  13. set_404()
  14. get( $query_var, $default = '' )
  15. set( $query_var, $value )
  16. get_posts()
  17. set_found_posts( $q, $limits )
  18. next_post()
  19. the_post()
  20. have_posts()
  21. rewind_posts()
  22. next_comment()
  23. the_comment()
  24. have_comments()
  25. rewind_comments()
  26. query( $query )
  27. get_queried_object()
  28. get_queried_object_id()
  29. __construct( $query = '' )
  30. __get( $name )
  31. __isset( $name )
  32. __call( $name, $arguments )
  33. is_archive()
  34. is_post_type_archive( $post_types = '' )
  35. is_attachment( $attachment = '' )
  36. is_author( $author = '' )
  37. is_category( $category = '' )
  38. is_tag( $tag = '' )
  39. is_tax( $taxonomy = '', $term = '' )
  40. is_comments_popup()
  41. is_date()
  42. is_day()
  43. is_feed( $feeds = '' )
  44. is_comment_feed()
  45. is_front_page()
  46. is_home()
  47. is_privacy_policy()
  48. is_month()
  49. is_page( $page = '' )
  50. is_paged()
  51. is_preview()
  52. is_robots()
  53. is_search()
  54. is_single( $post = '' )
  55. is_singular( $post_types = '' )
  56. is_time()
  57. is_trackback()
  58. is_year()
  59. is_404()
  60. is_embed()
  61. is_main_query()
  62. setup_postdata( $post )
  63. generate_postdata( $post )
  64. reset_postdata()
  65. lazyload_term_meta( $check, $term_id )
  66. lazyload_comment_meta( $check, $comment_id )

-

Источник WP_Query

Список изменений

С версии 1.5.0 Введена.
С версии 4.5.0 Removed the $comments_popup property.

Код WP Query: wp-includes/class-wp-query.php WP 5.2.4

Код слишком большой, смотрите его на отдельной странице...

Cвязанные функции

Из метки: query (запрос)

Еще из раздела: Классы

200 комментов
Полезные 15 Вопросы 4 Все
  • Дмитрий

    Надо сделать, что бы товары выводились по убыванию цены. Я пытался сделать и получилось, то, что выводит, только те товары, которые меньше или равно заданному значению, а как из сделать, что бы они выводились по убыванию?

    $arr = [
    				'id' => '5',
    				'meta_query' => [
    					[
    						'key' => 'price',
    						'value' => '10000',
    						'compare' => '<=',
    						'type' => 'NUMERIC',
    					]
    				],
    				'order' => 'DESC',
    			 ];
    
    			$recent = new WP_Query($arr); 
    
    1
    Ответить1.8 года назад #
  • Что-то подрасстроила меня WP_Query в плане производительности. Пишу сложную выборку из метаполей.

    array(
    	'relation' => 'AND',
    	array(
    		'value'   => array(100, 6999),
    		'type'    => 'numeric',
    		'compare' => 'BETWEEN',
    		'key'     => 'price',
    	),
    	array(
    		'value'   => array(3, 95),
    		'type'    => 'numeric',
    		'compare' => 'BETWEEN',
    		'key'     => 'size',
    	),
    	array(
    		'value'   => array(100, 500),
    		'type'    => 'numeric',
    		'compare' => 'BETWEEN',
    		'key'     => 'weight',
    	),
    	array(
    		'value'   => array('0-1', '1-2'),
    		'key'     => 'old',
    	),
    	array(
    		'value'   => 'нет',
    		'key'     => 'interactive',
    	),
    	array(
    		'value'   => array('Беларусь', 'Россия'),
    		'key'     => 'country',
    	),
    	array(
    		'value'   => array('Baby', 'Disnay'),
    		'key'     => 'brend',
    	)
    );

    Скорость загрузки - 20 секунд, без этого куска кода - 0.2сек. Это из 1000 записей.

    Ответить1.7 года назад #
    • campusboy3430 www.youtube.com/c/wpplus

      За удобство всегда приходилось платить. Напиши аналог такого запроса на wpdb, сколько будет выполнение?

      Ответить1.7 года назад #
      • Хех... легко сказать. Знать бы еще как это делается smile

        Ответить1.7 года назад #
        • campusboy3430 www.youtube.com/c/wpplus

          Ну ты же образно говоря обвиняешь WP_Query в медленности, хотя этот класс всего лишь формирует запрос, который выполнит база данных. Если предполагаешь, что она это делает крайне медленно, то надо написать запрос без WP_Query, который будет делать тоже самое и сравнить скорости. Иначе обвинения ложны smile

          1
          Ответить1.7 года назад #
          • Пардон. Это похоже я с базой данных напортачил. Тестирую на другом, с теми же параметрами. Все довольно быстро - 0.1-0.2 секунды. Беру свои слова обратно

            Ответить1.7 года назад #
            • В продолжение темы. Не могу понять, по какой причине растет время ответа запроса WP_Query. Стартует хорошо, 0.1-0.2 секунды. Затем, с каждой итерацией, время растет. Доходит аж до 10-20 секунд. Подскажите, в чем может быть причина?

              Ответить1.7 года назад #
              • campusboy3430 www.youtube.com/c/wpplus

                Она пытается всё кешировать. Я думаю дело в этом. Попробуй выставить параметры кеширования у неё или используй wp_suspend_cache_addition(). Это лишь моё предположение.

                2
                Ответить1.7 года назад #
                • Да, так и оказалось. Отключил кеш:

                  'no_found_rows'          => true,
                  'update_post_term_cache' => false,
                  'update_post_meta_cache' => false,
                  'cache_results'          => false

                  И все залетало smile

                  2
                  Ответить1.7 года назад #
                  • campusboy3430 www.youtube.com/c/wpplus

                    Спасибо за активность и конструктивные обсуждения, желание экспериментировать и искать истину. И делиться этим с другими! И всё это в уважительном тоне. Редкость для рунета. Спасибо ещё раз.

                    2
                    Ответить1.7 года назад #
    • Kama7630

      Такую выборку надо кэшировать - это сложный запрос, оптимизировать его особо не получится, даже если прямой запрос делать. Структура БД для таких запросов слаба...

      Кэшируй результат в транзитные опции или в файлы...

      2
      Ответить1.7 года назад #
  • Нашел крайне серьезный и неприятный баг WP_Query. В WP можно сказать что гуру, и написал на нем не один десяток сайтов, но теперь просто в шоке от того что обнаружил. В общем, если юзать вызов WP_Query сразу с аргументами, т.е.:

    $query = new WP_Query($args);

    то после этого массив постов забирайте в

    $query->posts

    но ни в коем случае (!!!), не делайте этого с помощью

    $query->get_posts()

    (как я всегда делал). Вообще не юзайте $query->get_posts().
    Результаты в массиве $query->posts и $query->get_posts() отличаются!!
    Посмотрев код wp-includes/class-wp-query.php увидел что при вызове WP_Query с аргументами, вызывается метод get_posts(), и когда мы вручную делаем последующий его вызов, результаты стают другими (не правильными).
    Если хотите, могу привести простой пример (пробовал на чистом WP разных версий).

    1
    Ответить1.7 года назад #
    • Kama7630

      Откуда такая техника, через $query->get_posts(). В начале этой статьи написано как надо юзать WP_Query... А вообще лучше почти всегда юзать get_posts()...

      Ответить1.7 года назад #
  • Подскажите как сортировать по произвольным полям, если это поля sub_field. Т.е. поля созданы с помощью ACF и объеденены в группу и соответственно это не просто get_field, а группа get_field с полями get_sub_field собственно вопрос как сортировать по этим полям?

    пробую так, но ...

    $group = get_field('name');
    $single = $group['single_name'];
    	$query = new WP_Query(
    		array(
    		'meta_query' => array(
    			array(
    			'key' => $single,
    			'value' => 'параметр'
    		)),
    Ответить1.6 года назад #
  • Константин yandex.ru

    Добрый день! Пытаюсь, чтобы в каталоге статей, каждая статья была обернута в тег "cтатья" и чтобы текст в "зе эксцерпт" был обернут в тег "параграф". Помогите пожалуйста

    <section class="articles-catalog">
    <?php    query_posts('cat=5');
     while (have_posts()) : the_post();?>
     <article>
    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
    <div class="thumbnail"><?php echo get_the_post_thumbnail(); ?></div> 
    	<p><?php the_excerpt();  </p>
    	endwhile; 
    	wp_reset_query();?>
    	</article>   
    			</section>
    Ответить1.5 года назад #
    • newbie34 yumchief.com
      <section class="articles-catalog">
      <?php query_posts('cat=5');
      while (have_posts()) : the_post();?>
      <article><h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
      <div class="thumbnail"><?php echo get_the_post_thumbnail(); ?></div> 
      <p><?php the_excerpt(); ?></p>
      <?php endwhile; 
      wp_reset_query(); ?>
      </article>   
      </section>
      1
      Ответить1.5 года назад #
  • Андрей

    Потребовалось сделать на аяксе выборку записей по датам из произвольных полей (по сути афиша) с помощью ряда условий в meta_query. Записи получал через WP_Query. Так вот все работало кроме сортировки. Я уже и так и сяк - параметры в query передаются, а сам SQL запрос неизменен. 4 часа бился, пока не передал параметры запроса в get_posts и о чудо - заработало! Все дело оказалось в параметре 'suppress_filters' => true, который get_posts принудительно указывает и тем самым отключает внутренние фильтры WP. Это я к чему - может быть в описании WP_Query сделать сноску, что в случае неадекватного поведения работы WP_Query надо указать 'suppress_filters' => true. Ни в одном мануале про это не написано ((

    4
    Ответить1.5 года назад #
    • Kama7630

      Добавил описание для параметра suppress_filters. Спасибо! thank_you

      Ответить9 мес назад #
  • богдан

    Хочу в стандартный поиск включить результаты по meta_value в таблице postmeta. Написал след код, но он не работает. Как правильно?

    add_action('pre_get_posts', 'dt_search_filter');
    function dt_search_filter( $query ){
    	$meta_query = $query->get('meta_query');
    	$meta_query = array(
    		'key' => 'fw_options',
    		'value' => $query,
    		'compare' =>  'LIKE'
    	);
    
    	$query->set('meta_query', array('relation' => 'OR', $meta_query));
    }
    Ответить1.3 года назад #
    • campusboy3430 www.youtube.com/c/wpplus

      У вас ошибка, надо так:

      function search_filter( WP_Query $query ) {
      	if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
      		$query->set( 'meta_query', array(
      			'relation' => 'OR',
      			array(
      				'key'     => 'fw_options',
      				'value'   => $query->query_vars['s'],
      				'compare' => 'LIKE'
      			)
      		) );
      	}
      }
      
      add_action( 'pre_get_posts', 'search_filter' );

      Но тогда будут находиться статьи, у которых есть только такая мета. Ниже идёт решение, когда обычный поиск дополняется поиском по мете.

      Взято со статьи Search WordPress by Custom Fields without a Plugin:

      <?php
      /**
       * Extend WordPress search to include custom fields
       *
       * https://adambalee.com
       */
      
      /**
       * Join posts and postmeta tables
       *
       * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
       */
      function cf_search_join( $join ) {
      	global $wpdb;
      
      	if ( is_search() ) {    
      		$join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
      	}
      
      	return $join;
      }
      add_filter('posts_join', 'cf_search_join' );
      
      /**
       * Modify the search query with posts_where
       *
       * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
       */
      function cf_search_where( $where ) {
      	global $pagenow, $wpdb;
      
      	if ( is_search() ) {
      		$where = preg_replace(
      			"/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
      			"(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
      	}
      
      	return $where;
      }
      add_filter( 'posts_where', 'cf_search_where' );
      
      /**
       * Prevent duplicates
       *
       * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
       */
      function cf_search_distinct( $where ) {
      	global $wpdb;
      
      	if ( is_search() ) {
      		return "DISTINCT";
      	}
      
      	return $where;
      }
      add_filter( 'posts_distinct', 'cf_search_distinct' );
      Ответить1.3 года назад #
  • Был удивлён, когда выяснил, что для случайной выборки значение 'rand' надо писАть строчными буквами. Прописными не работает.

    Ответитьгод назад #
Здравствуйте, !     Войти . Зарегистрироваться