Фильтр pre_get_posts — один из самых мощных инструментов в WordPress, позволяющий изменять основной запрос (WP_Query) до того, как он будет выполнен. Это дает возможность гибко настраивать выдачу записей, например, показывать только определённые категории на главной странице, исключать записи с определёнными метками, изменять порядок сортировки и многое другое. В этой статье разберёмся с практическими примерами использования фильтра pre_get_posts и покажем, как решать конкретные задачи.
Что такое фильтр pre_get_posts и зачем он нужен
Когда WordPress формирует страницу, он создает объект WP_Query, который содержит запрос к базе данных для получения нужных записей. По умолчанию этот запрос нацелен на отображение стандартных элементов, например, главной страницы, архива, страницы записей и так далее.
Фильтр pre_get_posts позволяет вмешаться в этот процесс и изменить параметры запроса до его выполнения. Это полезно, если вы хотите, чтобы на определённых страницах выводились не все записи, а только выбранные, или нужно изменить порядок сортировки без создания дополнительного кода.
Важно: фильтр применяется ко всем запросам, включая административную панель, поэтому всегда нужно фильтровать запросы, чтобы избежать ошибок.
Пример 1: Отображение только определенной категории на главной странице
Допустим, на главной странице сайта нужно показывать только записи из категории с ID 7. Для этого добавим следующий код в файл functions.php вашей темы или в отдельный плагин.
function wpbloger_pre_get_posts_main_category( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set( 'cat', '7' );
}
}
add_action( 'pre_get_posts', 'wpbloger_pre_get_posts_main_category' );
Здесь мы проверяем, что запрос не в админке (! is_admin()), что это главный запрос страницы ($query->is_main_query()) и что это именно главная страница ($query->is_home()). После этого фильтруем по категории с ID 7.
Пример 2: Исключение определенных записей из архива
Предположим, на странице архива блога нужно исключить записи с конкретенными ID (например, 12 и 34).
function wpbloger_exclude_posts_from_archive( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_archive() ) {
$query->set( 'post__not_in', array( 12, 34 ) );
}
}
add_action( 'pre_get_posts', 'wpbloger_exclude_posts_from_archive' );
Этот код проверит, что мы находимся на странице архива и изменит запрос, исключив записи с ID 12 и 34.
Пример 3: Сортировка записей на странице автора по дате по возрастанию
По умолчанию записи сортируются в порядке убывания даты (свежие первыми). Если нужно изменить порядок на обратный, сделаем так:
function wpbloger_change_author_order( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_author() ) {
$query->set( 'order', 'ASC' );
$query->set( 'orderby', 'date' );
}
}
add_action( 'pre_get_posts', 'wpbloger_change_author_order' );
Теперь на странице автора записи будут идти от самых старых к новым.
Частые ошибки при работе с pre_get_posts и как их избежать
1. Изменение запросов в админке без необходимости. Это может привести к некорректной работе административной панели. Всегда используйте проверку ! is_admin().
2. Отсутствие проверки, что запрос — главный. Фильтр применяется к любым запросам, в том числе дополнительным, например, запросам виджетов. Используйте $query->is_main_query() для ограничения.
3. Неправильное использование условий. Например, если нужно изменить запрос только на главной странице, обязательно применяйте условие $query->is_home() или другие соответствующие условные теги.
Полезные плагины для работы с запросами и фильтрами WordPress
Для расширенной работы с запросами можно использовать плагины, которые помогут визуально управлять выводом записей или создавать сложные выборки без кода:
- Clearfy Pro — оптимизация и управление запросами, отключение лишних запросов.
- WPRemark — расширение возможностей комментариев и их выборки.
- ABC Pagination — удобная навигация по страницам с поддержкой кастомных запросов.
Кастомный пример: фильтрация записей по произвольному метаполю
Часто нужно вывести записи, у которых в метаполях есть определенное значение. Допустим, у нас есть метаполе wpbloger_featured, и мы хотим вывести только записи, где оно равно yes.
function wpbloger_filter_by_meta( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$meta_query = array(
array(
'key' => 'wpbloger_featured',
'value' => 'yes',
'compare' => '=',
),
);
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'wpbloger_filter_by_meta' );
Этот код отфильтрует главную страницу, показывая только записи с нужным метаполем.
Выводы и рекомендации
Фильтр pre_get_posts — незаменимый инструмент для разработчиков, позволяющий глубоко настраивать логику вывода контента в WordPress без создания дополнительных шаблонов или сложных запросов вручную. Однако важно грамотно использовать проверки, чтобы не нарушить работу сайта и не вызвать конфликтов.
Экспериментируйте с параметрами запроса, изучайте документацию к WP_Query и используйте плагины для упрощения сложных задач. Так вы сможете создавать уникальные и удобные решения для сайтов на WordPress.