WordPress: вывод записей произвольных типов (Custom Post Types)

Владимир | | PHP, Web разработка, WordPress.

wordpress custom queries

На сегодняшний день движок WordPress довольно интенсивно развивается. Во всяком случае изменения в версиях с 2.8 по 3.1 добавляют WP возможности полноценных CMS. Большинство из этих возможностей должны быть активированы на уровне темы (или плагина), поэтому сразу после установки WP вы работаете с ним как с обычным блоговым движком.

Вроде бы все правильно. Если какие-то возможности вам не нужны, вы их не используете. Но при этом возникает серьёзная проблема с документацией. Дело в том, большинство примеров и в Кодексе, и в других источниках, ориентированы на самый простой случай – дефолтную инсталляцию WP. Как только вы активируете дополнительные возможности ко многим рекомендациям нужно относится очень аккуратно.

Об одном из таких примеров я хочу рассказать в этой статье.

Предположим, вы решили использовать произвольные типы записей (custom post types). Создать их достаточно просто и на эту тему есть масса статей, поэтому подробно останавливаться на этом моменте не будем.

В большинстве случаев достаточно добавить следующий код в файл functions.php вашей темы.

register_post_type('gadgets',
	array(
		'labels' => array(
			'name' => __('Gadgets'),
			'singular_name' => __('Gadget'),
			//остальные переводы
		),
		'public' => true,
		'publicly_queryable' => true,
		'query_var' => true,
		'taxonomies' => array('category','post_tag'),
		'supports' => array('title','editor','author','thumbnail','excerpt','comments'),
		'rewrite' => array('slug' => 'gadgets'),
		//другие настройки
	)
);

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

http://blog.url/gadgets

Теперь обратите внимание, что для этого типа записей мы используем такие же категории, как и для типа Post (строка 11).

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

Происходит это потому что WP при формировании запроса к базе данных явно указывает тип поста. И по-умолчанию этот тип – post.

К сожалению, в подобных случаях не все авторы тем хотят вникать в нюансы работы движка и просто используют функцию query_posts. Я понимаю, что примеры её использования приведены в статье The Loop, но там предполагается, что вам нужно создать дополнительный цикл на странице. Т.е., например, вывести основной список записей и ещё какой-нибудь дополнительный список, с фильтрацией по определённым условиям.

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

Решается задача достаточно просто.

function prefix_pre_get_posts($query) {
     if ($query->is_category) {
          $query->set('post_type', 'any');
     }
     return $query;
}

add_action('pre_get_posts', 'prefix_pre_get_posts');

Здесь мы назначаем собственный обработчик события (action) pre_get_posts. Как следует из названия, это событие возникает непосредственно перед отправкой запроса к БД. В первом параметре обработчик получает объект типа WP_Query, который формирует запрос к базе.

Прежде всего, мы проверяем, что в данный момент создаётся страница категории (строка 2). А затем изменяем атрибут post_type. По-умолчанию он равен post. Не забывайте, что обработчик обязательно должен вернуть изменённый (или неизменённый) объект WP_Query.

Вообще, если вы планируете работать с новыми возможностями WP (произвольными типами записей, таксономиями, форматами записей), то научиться работать с WP_Query нужно обязательно. Встроенными функциями движка здесь вы не обойдетесь.

В целом, этого и следовало ожидать, чем больше возможностей у движка, тем больше времени придётся потратить на его изучение 😉

Успехов!

Интересно почитать

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