В WordPress часто возникает задача изменить выборку записей на странице блога, архиве, категории или на главной странице без изменения кода шаблона напрямую. Для этого идеально подходит хук pre_get_posts. В этой статье подробно разберём, как правильно использовать pre_get_posts для тонкой настройки запросов к базе данных, чтобы фильтровать, исключать или добавлять записи по разным параметрам.
Что такое хук pre_get_posts и зачем он нужен
Хук pre_get_posts срабатывает перед выполнением основного запроса WordPress, то есть до того, как будут получены записи из базы данных. Это позволяет изменить параметры запроса, например, добавить условие по меткам, таксономиям, типам записей, датам и многому другому.
Пример классического применения — исключение определённых категорий из главного блога или изменение количества выводимых записей.
Важно помнить, что pre_get_posts срабатывает для всех запросов — как для фронтенда, так и для административной панели, поэтому важно правильно фильтровать, где именно вы хотите изменить запрос.
Как правильно фильтровать запросы с помощью pre_get_posts
Для безопасного использования нужно в функции-обработчике проверять, что это именно основной запрос и что мы находимся на нужной странице. Для этого используются методы объекта WP_Query:
$query->is_main_query()— проверка, что это основной запрос;$query->is_admin()— проверка, что запрос в админке;- и другие условные теги, например,
is_home(),is_category(),is_archive()и т.д.
Это позволяет избежать нежелательных изменений в запросах, например, на страницах админки или в сайдбаре.
Пример 1: Исключение категории из главной страницы блога
Допустим, есть категория с ID 12, записи из которой нужно исключить из главной страницы блога.
add_action('pre_get_posts', 'wpblog_pre_get_posts_exclude_category');
function wpblog_pre_get_posts_exclude_category($query) {
if (!is_admin() && $query->is_main_query() && $query->is_home()) {
$query->set('cat', '-12'); // минус означает исключение категории
}
}Этот код исключит все записи категории с ID 12 из главной страницы блога.
Пример 2: Фильтрация записей по пользовательскому полю (meta_query)
Иногда нужно выводить только записи, у которых в метаполях хранится определённое значение, например, только статьи с рейтингом 5.
add_action('pre_get_posts', 'wpblog_pre_get_posts_filter_by_meta');
function wpblog_pre_get_posts_filter_by_meta($query) {
if (!is_admin() && $query->is_main_query() && is_archive()) {
$meta_query = array(
array(
'key' => 'rating',
'value' => '5',
'compare' => '=',
),
);
$query->set('meta_query', $meta_query);
}
}Так будут выбираться только записи с метаполем rating, равным 5 на страницах архивов.
Пример 3: Добавление нескольких условий и сортировка
Можно комбинировать условия и менять порядок сортировки, например, вывести только записи типа «product» с ценой больше 1000, отсортированные по цене по убыванию.
add_action('pre_get_posts', 'wpblog_pre_get_posts_filter_products');
function wpblog_pre_get_posts_filter_products($query) {
if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
$meta_query = array(
array(
'key' => 'price',
'value' => 1000,
'type' => 'NUMERIC',
'compare' => '>',
),
);
$query->set('meta_query', $meta_query);
$query->set('orderby', 'meta_value_num');
$query->set('meta_key', 'price');
$query->set('order', 'DESC');
}
}Этот код отлично подходит для интернет-магазинов или каталогов с пользовательскими типами записей.
Советы и важные моменты при работе с pre_get_posts
Не забывайте про проверку is_main_query и is_admin
Без этих проверок изменения будут применяться ко всем запросам, включая запросы в админке, что может привести к багам.
Используйте параметры set для изменения запроса
Метод $query->set( $key, $value ) позволяет устанавливать любые параметры WP_Query, такие как cat, post_type, meta_query, orderby и др.
Отладка с помощью var_dump и WP_Query::request
Для отладки можно вывести SQL-запрос с помощью var_dump($query->request) внутри функции, чтобы увидеть, как формируется запрос к базе.
Полезные плагины для работы с запросами и фильтрацией записей
Хотя pre_get_posts даёт мощный инструмент для кастомизации, иногда удобнее использовать готовые плагины:
- Query Monitor — помогает отлаживать запросы и видеть параметры WP_Query;
- Search & Filter — удобный интерфейс для создания сложных фильтров на сайте;
- Clearfy Pro — оптимизирует работу сайта и улучшает управление запросами.
Заключение
Хук pre_get_posts — один из самых мощных инструментов для разработчика WordPress, позволяющий гибко фильтровать и настраивать выборку записей без изменения шаблонов. Главное — внимательно проверять контекст запроса и использовать правильные условия, чтобы избежать конфликтов и багов.
Используйте предоставленные примеры как базу, адаптируя под свои задачи, и вы легко сможете реализовать любые требования по кастомизации контента.