WP_Query()

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

Про класс WP_Query можно сказать в двух словах — нужен для вывода постов, например:

  • из определенной категории и(или) по определенным тегам,
  • за определенный промежуток времени,
  • создание виджетов «Новое на блоге», «Популярные» и «Случайные записи»,
  • возможность отбора и сортировки постов по произвольным полям,
  • расширенный поиск на сайте и и т.д. (возможностей действительно очень много)
примеры использования WP_Query
Эта картинка была загружена на мой сайт ещё в 2012-м году, решил оставить её тут для истории 🙂

Циклов на странице может находиться сколько угодно.

Это было небольшое вступление для тех, кто не в курсе.

Использование, быстрый пример

В обоих следующих примерах выводятся ссылки на 5 самых комментируемых записей на блоге:

// в массиве задаем все необходимые параметры (более подробно о параметрах чуть ниже)
$args = array(
	'posts_per_page' => 5,
	'orderby' => 'comment_count'
);
 
// создаем новый объект
$q = new WP_Query( $args );
 
// проверяем, существуют ли посты по заданным параметрам (необязательно, но рекомендую)
if( $q->have_posts() ) :
 
	// затем запускаем цикл
	while( $q->have_posts() ) : $q->the_post();
 
		// выводим например ссылку на каждый пост
		echo '<a href="' . get_permalink() . '">' . get_the_title() . '</a>';
	endwhile;
endif;
 
// восстанавливаем глобальную переменную $post
wp_reset_postdata();
  • Вообще не обязательно использовать условия и циклы в формате записи с двоеточием : и endif или endwhile, но очень часто бывает, что внутри цикла происходит закрытие тегов php и вывод в HTML, тогда условия становятся так удобнее.
  • Методы $q->have_posts() и $q-the_post() идентичны аналогичным функциям основного цикла – have_posts() и the_post() соответственно.
  • Также можете отдельно почитать про функции get_permalink() и get_the_title(), которые не имеют никаких параметров заметьте, потому что получают значение ID поста из глобальной переменной, которая устанавливается классом, именно поэтому в конце мы и используем сброс глобальной переменной функцией wp_reset_postdata(), чтобы у вас не поломались другие циклы на сайте.

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

$q = new WP_Query( "posts_per_page=5&orderby=comment_count" );

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

$q = new WP_Query( "posts_per_page=$per_page&orderby=comment_count" );

Дальше пойдет описание параметров, ещё есть отдельный пост про методы и свойства.

Параметры класса WP_Query

Авторство

author
(целое число) ID автора, посты которого выводим.
author_name
(строка) «user_nicename» автора, обычно совпадает с логином.
author__in
(массив) ID нескольких авторов в виде массива.
author__not_in
(массив) ID нескольких авторов в виде массива, чьи посты мы хотим исключить из вывода.

Можно вывести посты сразу нескольких авторов: $q = new WP_Query( 'author=4,5,8,15' );

Или вот так

$q = new WP_Query( array( 'author__in' => array( 4, 5, 8, 15 ) ) );

Рубрики, метки, таксономии

Когда-то давно в WordPress не существовало произвольных таксономий, были только рубрики и метки. Потом появились таксономии и новый параметр для них – tax_query, но конечно же никто не будет удалять старые параметры ради обратной совместимости.

Тем не менее я не хочу учить вас каким-то «древним приколам», поэтому давайте сразу – если говорим о выводе постов из любых таксономий (даже из стандартных, типо рубрик и меток), то сразу один параметр – tax_query.

tax_query
(массив) Позволяет построить вывод постов по любым условиям из произвольных таксономий

Чтобы с этим было легче разобраться, нужен пример, начнём с максимально легкого

// выводим посты из элемента таксономии gta_vice_city таксономии game
$params = array(
	'tax_query' => array(
		array(
			'taxonomy' => 'game',
			'field' => 'slug',
			'terms' => 'gta_vice_city'
		)
	)
);
$query = new WP_Query( $params );
  • На строчке 5 у нас указывается название таксономии в ключе taxonomy, это значение может быть category для рубрик или post_tag для меток.
  • На строчке 6 – параметр field принимает одно из трёх значений – id (по умолчанию), slug или name. В зависимости от того, что вы в нём указали, то и должны передать в параметр terms. Например у меня указан slug, значит я и передаю на следующей строке ярлык таксономии gta_vice_city.
  • На строке 7 мы видим параметр terms, который и принимает термины, из которых выводим посты, но обратите внимание, что мы можем туда также передавать и несколько элементов в виде массива.
  • Строчка 3-4 – обратите внимание, что tax_query содержит массив в массиве! Это важно запомнить, иначе у вас ничего не будет работать. Для чего это нужно? А для того, чтобы можно было накидать много условий! Покажу вам это чуть ниже:
// выводим посты из элемента таксономии gta_vice_city таксономии game
// ИЛИ из рубрики uncategorized, то есть И ТЕ И ДРУГИЕ В ОДНОМ ЦИКЛЕ
$params = array(
	'tax_query' => array(
		array(
			'taxonomy' => 'game',
			'field' => 'slug',
			'terms' => 'gta_vice_city'
		),
		array(
			'taxonomy' => 'category',
			'field' => 'slug',
			'terms' => 'uncategorized'
		)
	)
);
$query = new WP_Query( $params );

Вы думаете о том же, о чём и я? 😁

В примере мы передали два условия в виде двух массивов внутрь tax_query (можем передать и три), как я уже сказал, то выведутся посты, удовлетворяющие любому условию, и что сделать, чтобы посты удовлетворяли обоим условиям сразу? Тут нам поможет параметр relation, который закидываем вместе с массивами на том же уровне. Вот так:

$params = array(
	'tax_query' => array(
		'relation' => 'AND', // по умолчанию значение OR
		array(
			'taxonomy' => 'game',

Теперь оба условия будут выполняться.

Продолжаем апгрейдить наш tax_query – а что, если мы хотим не вывести также и посты из рубрики uncategorized, а наоборот исключить их из неё? Каждый мини-массив-условие таксономии помимо параметров taxonomy, field и terms может принимать ещё и параметр operator!

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

array(
	'taxonomy' => 'category',
	'field' => 'slug',
	'operator' => 'NOT IN', // не принадлежащие рубрике uncategorized
	'terms' => 'uncategorized'
)

Давайте я наверное опишу значения параметра operator, а то у многих как-то кривовато переведено 😋

operator
  • IN – посты содержат указанный термин, либо содержат один из терминов, переданных в массиве.
  • NOT IN – посты, не содержащие указанный термин и, если передан массив, то не содержащие ни один из терминов массива.
  • AND – посты, содержащие все термины массива.
  • NOT EXISTS посты, не содержащие ни один из терминов указанной таксономии, параметр terms тут уже не нужен.
  • EXISTS посты, содержащие любой термин из указанной таксономии, параметр terms тут не нужен.

Думаю ещё одну вещь я должен вам показать с tax_query, это когда у нас много-много разных условий!

$q = new WP_Query( 
	array(
		'tax_query' => array(
			'relation' => 'OR',
			array(
				// условие 1
				'relation' => 'AND',
				array(
					// условие 1.1
				),
				array(
					// условие 1.2
				)
			),
			array(
				// условие 2
				'relation' => 'AND',
				array(
					// условие 2.1
				),
				array(
					// условие 2.2
				)
			)
		)
	)
);

Как вам такое? 😁 И таких вложенностей может быть больше.

В данном примере у нас должно выполнять ИЛИ условие 1 ИЛИ 2, которые в свою очередь выполняются, если их дочерние подусловия оба выполнены!

Записи, Страницы, Типы постов

Опять-таки, как и с таксономиями – ранее в WordPress были сами по себе записи и страницы, а теперь это всё одно – посты, лишь разных типов. Поэтому снова можем сократить пару ненужных параметров.

post_type
(строка|массив) Посты какого типа нужно вывести? Внимание – по умолчанию post, значит только записи! Напоминаю значения, которые он может принимать:
  • post — записи, посты (по умолчанию),
  • page — страницы,
  • attachment — вложения, файлы
  • revision — редакции (не черновики),
  • any — все, кроме редакций и постов с параметром exclude_from_search=true,
  • созданный вами тип поста, например game;
p
(целое число) Единственный ID поста, который вы хотите получить через цикл.
post__in
(массив) какие посты следует включить в цикл.
$q = new WP_Query( array( 'post__in' => array( 3, 7, 14, 15, 21 ) ) );
post__not_in
(массив) какие посты не следует включать в цикл.
post_parent
(целое число) Выводим все дочерние посты, ID родителя которых равен указанному, например new WP_Query( 'post_parent=9' )
post_parent__in
(массив) Все посты, родители которых указанны в массиве.
post_parent__not_in
(массив) Все посты, родители которых не указанны в массиве.
name
(строка) Ярлык записи, например new WP_Query( 'name=o-nas' )
post_name__in
(массив) Посты, ярлыки которых перечислены в массиве.

Прилепленные посты

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

прилепить пост на главную страницу

Такие посты можно тоже по-разному отфильтровать при помощи параметров WP_Query.

ignore_sticky_posts
(логическое) игнорировать приоритет прилепленных постов, по умолчанию — false.

А теперь выведем все посты, которые были отмечены, как прилепленные. В этом случае, конечно же, можно отключить (а можно и не отключать) их повышенный приоритет перед другими постами:

$params = array(
	'posts_per_page' => -1,
	'post__in'  => get_option( 'sticky_posts' ), // массив, содержащий IDы всех прилепленных постов
	'ignore_sticky_posts' => 1
);
 
$q = new WP_Query( $params );

Статусы постов

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

Форматы записей

Форматы записей выводятся по типу таксономий, например:

$params = array(
	'tax_query' => array( // про tax_query написано чуть выще
		array(
			'taxonomy' => 'post_format', // таксономия форматов
			'field'    => 'slug', // значение этого поля обязательно slug
			'terms'    => array( 'post-format-quote' ), // название одного или нескольких форматов в виде массива
		),
	),
);
$q = new WP_Query( $params );

Параметры постраничной навигации

posts_per_page
(целое число) количество записей, отображаемых на одной странице.

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

$q = new WP_Query( array( 'posts_per_page' => -1 ) );
paged
(целое число) отобразить записи, находящиеся на определенной странице.
offset
(целое число) количество записей, которые нужно пропустить. Если вы указываете значение для offset, то параметр paged будет проигнорирован и ваша пагинация может сломаться. Параметр offset же сам по себе будет проигнорирован при установке posts_per_page в значение -1.

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

orderby
(строка) сортировать по:
  • none — не сортировать,
  • ID — по id,
  • author — по имени автора,
  • title — по заголовку,
  • name – по ярлыку записей,
  • type – по названию типа поста,
  • date — по дате публикации (по умолчанию),
  • modified — по дате последнего изменения,
  • parent — по ID родительских постов,
  • rand — случайным образом,
  • comment_count — по количеству комментариев (начиная с версии 2.9),
  • menu_order — сортировать по указанному порядку, по умолчанию в WordPress уже есть инструменты для установки собственного порядка страниц и вложений:
    указываем порядковый номер в метабоксе атрибутов страницы
    сортировка изображений, вложенных в пост
  • relevance – по релевантности при использовании поиска, это работает таким образом, что сначала выведутся записи, когда поисковая фраза нашлась в заголовке и совпала полностью, затем, если все поисковые слова присутствуют в заголовке записи, затем – если хотя бы одно поисковое слово есть в заголовке и затем – если поисковая фраза нашлась и совпала полностью в контенте поста.
  • meta_value — по значению мета-данных поста (произвольного поля), при этом в цикле должен присутствовать параметр meta_key используется только для сортировки строковых значений,
  • meta_value_num — по значению произвольного поля, для сортировки чисел,
  • post__in — использовать порядок, заданный в параметре post__in, параметр направления сортировки order при этом будет проигнорирован.
  • post_name__in — использовать порядок, заданный в параметре post_name__in, параметр направления сортировки при этом будет проигнорирован.
  • post_parent__in — использовать порядок, заданный в параметре post_parent__in, параметр направления сортировки при этом будет проигнорирован.

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

$q = new WP_Query( array( 'orderby' => 'author title' ) );

Эту запись также возможно записать в таком виде:

$q = new WP_Query( array( 
	'orderby' => array(
		'author' => 'ASC',
		'title'	=> 'DESC',
 	)
);

В WordPress 4.2 появилась возможность передавать в orderby нечисловой индекс массива meta_query, подробнее читайте здесь.

order
(строка) порядок сортировки.
  • ASC — по возрастанию (1, 2, 3; a, b, c),
  • DESC — по убыванию (3, 2, 1; c, b, a) (по умолчанию);

Дата и время

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

year
(целое число) год публикации,
monthnum
(целое число) месяц публикации (от 1 до 12),
w
(целое число) неделя публикации (от 0 до 53),
day
(целое число) день публикации (от 1 до 31),
hour
(целое число) час (от 0 до 23),
minute
(целое число) минута (от 0 до 60),
second
(целое число) секунда (от 0 до 60);

Все посты, опубликованные 20 декабря 2011:

$q = new WP_Query( "year=2011monthnum=12&day=20" );

Читайте более подробно о том, как вывести посты, опубликованные между двумя датами.

Метаданные, произвольные поля

meta_key
(строка) название произвольного поля,
meta_value
(строка) значение произвольного поля,
meta_value_num
(число) значение произвольного поля,
meta_compare
(строка) оператор сопоставления значений произвольного поля, может принимать значения: ‘!=’, ‘>’, ‘>=’, ‘<' или '<='. По умолчанию '=';

Отобразить все записи, в которых значение произвольного поля «color» равно «blue».

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

Отобразить записи, в которых значение любого произвольного поля равно «blue».

$q = new WP_Query( array( 'meta_value' => 'blue' ) );

А в этом варианте выводятся посты, у которых значение произвольного поля «color» не равно «red».

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

Начиная с версии WordPress 3.1 параметры произвольных полей можно задавать через массив meta_query.

meta_query
(массив) состоит из:
вложенный массив
(массив) Является условием для какого-то определённого ключа произвольного поля. Содержит следующие элементы:
  • key (строка) — название произвольного поля,
  • value (строка|массив) — значение произвольного поля (параметр может быть опущен, если для сравнения используются операторы ‘EXISTS’ или ‘NOT EXISTS’ — доступны, начиная с 3.5 )
  • compare (строка) — оператор сопоставления, возможные значения: ‘=’ (по умолчанию), ‘!=’, ‘>’, ‘>=’, ‘<‘, ‘<=’, ‘LIKE’, ‘NOT LIKE’, ‘IN’, ‘NOT IN’, ‘BETWEEN’, ‘NOT BETWEEN’, ‘EXISTS’ и ‘NOT EXISTS’,
  • type (строка) — тип данных значения произвольного поля, например ‘NUMERIC’, ‘BINARY’, ‘CHAR’ (по умолчанию), ‘DATE’, ‘DATETIME’, ‘DECIMAL’, ‘SIGNED’, ‘TIME’, ‘UNSIGNED’.
relation
(строка) описывает логическое взаимодействие между массивами, содержащимися в meta_query, может принимать значения OR или AND.

В этом примере выводим анкеты людей, которые разбираются в WordPress или DLE, и им от 18 до 25 лет.

$args = array(
	'post_type' => 'resume',
	'meta_query' => array(
		'relation' => 'AND',
		array(
			'key' => 'cms',
			'value' => array( 'wordpress', 'dle' ),
			'compare' => 'IN'
		),
		array(
			'key' => 'age',
			'value' => array( 18, 25 ),
			'type' => 'numeric',
			'compare' => 'BETWEEN'
		)
	)
);
 
$query = new WP_Query( $args );

Множество примеров использования meta_query вы можете найти тут.

s
(строка) поиск постов по указанному ключевому слову, например:
$q = new WP_Query( array( 's' => 'wordpress' ) );

Формат возвращаемого результата

fields
(строка) в каком виде выводить результат:
  • ids — массив составленный из ID элементов (постов), кстати посмотреть на вид самих массивов вы можете через функцию print_r() или заглянув в пост про get_terms(),
  • id=>parent — ассоциативный массив состоящих из ID элементов и ID их родителей, при этом, если родительского элемента не существует, то возвращается 0.
  • По умолчанию выводится массив объектов постов.
$q = new WP_Query( array(
	'post_type' => 'page',
	'posts_per_page' => -1,
	'fields' => 'id=>parent'
) );
print_r( $q );
/*
Результат примерно такой:
Array ( [1] => 0 [4] => 0 [11] => 4 )
*/

Миша

Недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

Сам же я впервые познакомился с WordPress в 2009 году. Организатор WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда сделаем вам всё на лучшем уровне.

Комментарии — 155

Оставить комментарий

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, если же код – меньше одной строчки, то можно и в <code></code>.