В WordPress одна из самых мощных возможностей для кастомизации запросов — это использование хука pre_get_posts. Этот хук позволяет изменять основной запрос WordPress до того, как он будет выполнен, давая полный контроль над тем, какие записи будут получены и отображены.
Что такое хук pre_get_posts и зачем он нужен
Хук pre_get_posts срабатывает перед выполнением WP_Query, основного класса для выборки записей. Он позволяет модифицировать параметры запроса, например, изменить типы записей, таксономии, порядок сортировки, количество записей и многое другое.
Использование этого хука особенно полезно, когда нужно изменить поведение главного цикла WordPress (main query) на страницах архива, главной странице, странице поиска и других, без необходимости создавать отдельные WP_Query.
Однако работать с pre_get_posts нужно аккуратно, чтобы не нарушить логику сайта и избежать конфликтов с другими плагинами или темами.
Пример: как изменить главную страницу, чтобы показывать записи из нескольких категорий
Предположим, вам нужно на главной странице выводить посты только из категорий «Новости» (id=5) и «Обзоры» (id=8). Для этого можно использовать следующий код в файле functions.php вашей темы или в отдельном плагине:
function wphow_pre_get_posts_main_query( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set( 'category__in', array(5, 8) );
$query->set( 'posts_per_page', 10 );
}
}
add_action( 'pre_get_posts', 'wphow_pre_get_posts_main_query' );Здесь мы проверяем, что запрос не в админке, что это главный запрос и что мы на главной странице блога. Затем задаём параметр category__in, чтобы выводились посты из нужных категорий, и ограничиваем количество постов до 10.
Использование сложных условий с relation и мета-запросами
Иногда нужно фильтровать записи по нескольким условиям одновременно, например, по нескольким мета-полям или сочетанию таксономий и мета-полей. Для этого в pre_get_posts можно добавить массивы условий с параметром relation.
Пример: вывести записи, которые принадлежат категории «Новости» и у которых пользовательское поле «important» равно «1» или «featured» равно «yes».
function wphow_pre_get_posts_complex_condition( $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_archive() ) {
$meta_query = array(
'relation' => 'OR',
array(
'key' => 'important',
'value' => '1',
'compare' => '='
),
array(
'key' => 'featured',
'value' => 'yes',
'compare' => '='
),
);
$query->set( 'category_name', 'novosti' );
$query->set( 'meta_query', $meta_query );
$query->set( 'posts_per_page', 15 );
}
}
add_action( 'pre_get_posts', 'wphow_pre_get_posts_complex_condition' );Здесь мы комбинируем таксономию и мета-запрос с логикой OR, что позволяет гибко фильтровать записи с нужными параметрами.
Как отладить и проверить, что pre_get_posts работает корректно
Для отладки можно использовать вывод параметров запроса с помощью функции var_dump или error_log. Например, добавьте в функцию:
error_log( print_r( $query->query_vars, true ) );Это позволит увидеть в логах сервера, какие параметры были установлены перед выполнением запроса.
Также полезно использовать плагины, такие как Query Monitor, которые показывают текущие запросы и их параметры прямо в админке WordPress.
Советы по использованию pre_get_posts без ошибок
- Всегда проверяйте
is_main_query(), чтобы не изменить побочные запросы (например, виджеты или пользовательские WP_Query). - Используйте условные теги WordPress, например,
is_home(),is_archive(),is_search(), чтобы ограничить область действия изменений. - Не забывайте про
! is_admin(), чтобы не менять запросы в административной зоне. - Если работаете с мета-запросами, внимательно продумывайте структуры
meta_queryс правильнымrelationи условиями. - Тестируйте изменения на локальном или тестовом сайте, чтобы избежать ошибок на рабочем ресурсе.
Пример плагина для расширенного фильтра записей на сайте
Если хотите собрать функционал в отдельный плагин, можно создать простой плагин с таким кодом:
<?php
/**
* Plugin Name: WPhow Advanced Query Filter
* Description: Расширенный фильтр записей с использованием pre_get_posts.
* Version: 1.0
* Author: WPHow
*/
function wphow_advanced_query_filter( $query ) {
if ( ! is_admin() && $query->is_main_query() && ( $query->is_home() || $query->is_archive() ) ) {
// Пример сложного условия
$meta_query = array(
'relation' => 'AND',
array(
'key' => 'custom_flag',
'value' => 'yes',
'compare' => '='
),
array(
'key' => 'rating',
'value' => 4,
'type' => 'NUMERIC',
'compare' => '>='
),
);
$query->set( 'meta_query', $meta_query );
$query->set( 'posts_per_page', 12 );
}
}
add_action( 'pre_get_posts', 'wphow_advanced_query_filter' );Этот плагин добавляет фильтр, который выводит главную страницу и архивы с записями, у которых мета-поле custom_flag равно «yes» и рейтинг больше либо равен 4.
Для более удобного управления можно добавить настройки в админку, но даже без этого код даёт мощный инструмент для кастомизации выборки.
Заключение
Хук pre_get_posts — это мощный и гибкий инструмент для разработчиков WordPress, который позволяет создавать сложные условия выборки записей без создания новых WP_Query и без модификации шаблонов. Правильное и аккуратное использование этого хука помогает создавать профессиональные и адаптивные сайты с точным контролем над контентом.
Для расширения функционала также можно использовать плагины из WPSHOP, например, Clearfy Pro для оптимизации или Expert Review для отзывов с фильтрами, которые можно интегрировать с кастомными запросами.