В WordPress часто возникает задача изменить запрос главного цикла или произвольных запросов для вывода постов. Для этого идеально подходит хук pre_get_posts. В этой статье подробно разберём, как правильно использовать этот хук для фильтрации постов, изменяя параметры запроса до его выполнения.
Что такое хук pre_get_posts и зачем он нужен
Хук pre_get_posts вызывается перед выполнением основного запроса WordPress (WP_Query). Это событие даёт возможность изменить параметры запроса, например, изменить типы записей, таксономии, порядок сортировки, количество постов и многое другое.
В отличие от фильтра posts_where или posts_join, здесь мы работаем с объектом запроса, что более удобно и безопасно. Кроме того, это позволяет избежать лишних запросов к базе и улучшить производительность.
Тем не менее, с этим хуком нужно работать аккуратно, особенно если изменяется главный запрос, чтобы не нарушить работу шаблона и пагинацию.
Основные параметры WP_Query, доступные для изменения в pre_get_posts
Через объект запроса ($query) можно менять практически любые параметры WP_Query:
post_type— типы записей для выборки;posts_per_page— количество постов на страницу;orderиorderby— сортировка;tax_query— фильтрация по таксономиям;meta_query— фильтрация по кастомным полям;- И другие параметры WP_Query.
Важно проверять, что мы меняем нужный запрос, обычно проверяют $query->is_main_query() или другие условия, чтобы не повлиять на админку или другие запросы.
Пример 1: Фильтрация главного запроса на главной странице
Допустим, нам нужно на главной странице выводить только записи типа post, исключая страницы или другие типы, а также ограничить количество постов до 5.
add_action('pre_get_posts', 'wptemy_pre_get_posts_filter_main_query');
function wptemy_pre_get_posts_filter_main_query($query) {
if (!is_admin() && $query->is_main_query() && is_home()) {
$query->set('post_type', 'post');
$query->set('posts_per_page', 5);
$query->set('order', 'DESC');
$query->set('orderby', 'date');
}
}
Этот код исключает из главного цикла все, кроме стандартных записей, и ограничивает вывод 5 свежими постами.
Пример 2: Фильтрация записей по таксономии в пользовательском архиве
Если у вас есть кастомный тип записей product с таксономией product_cat, и нужно вывести на архивной странице только продукты из категории «электроника».
add_action('pre_get_posts', 'wptemy_filter_products_by_category');
function wptemy_filter_products_by_category($query) {
if (!is_admin() && $query->is_main_query() && is_post_type_archive('product')) {
$tax_query = array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => 'elektronika',
),
);
$query->set('tax_query', $tax_query);
}
}
Такой фильтр позволит автоматически показывать только товары из нужной категории без дополнительных параметров в URL.
Пример 3: Фильтрация по метаполям (custom fields)
Если вы хотите вывести на странице архива записи, у которых кастомное поле featured установлено в значение yes, можно использовать мета-запрос:
add_action('pre_get_posts', 'wptemy_filter_featured_posts');
function wptemy_filter_featured_posts($query) {
if (!is_admin() && $query->is_main_query() && is_archive()) {
$meta_query = array(
array(
'key' => 'featured',
'value' => 'yes',
'compare' => '=',
),
);
$query->set('meta_query', $meta_query);
}
}
Этот способ часто используется для вывода отобранных записей или избранного контента.
Практические советы при работе с pre_get_posts
- Всегда проверяйте, что вы меняете именно нужный запрос, используя
is_main_query()и условные теги (например,is_home(),is_archive(),is_post_type_archive()). - Не меняйте запросы в админке без крайней необходимости, чтобы избежать багов.
- Если добавляете сложные условия с несколькими таксономиями и метаполями, объединяйте их через
tax_queryиmeta_queryс правильными параметрамиrelation. - Для дебага используйте
var_dump($query);или плагины типа Query Monitor, чтобы проверить итоговые параметры запроса.
Совместимость с плагинами и темами
Если вы используете темы от WPSHOP (например, JournalX, Root или Reboot), то они корректно поддерживают стандартные хуки WordPress, включая pre_get_posts. Это значит, что ваши дополнительные фильтры не вызовут конфликтов.
В некоторых случаях полезно комбинировать pre_get_posts с плагинами для оптимизации, например, Clearfy Pro, который может помочь отключить ненужные запросы и улучшить производительность.
Заключение
Хук pre_get_posts — мощный инструмент для тонкой настройки запросов в WordPress. С его помощью можно решать широкий спектр задач по фильтрации и сортировке контента без необходимости создавать дополнительные запросы вручную или модифицировать шаблоны.
Используйте проверку условий и внимательно тестируйте изменения, чтобы избежать проблем с отображением и пагинацией.