В WordPress для изменения выборки записей перед их выводом используется мощный хук pre_get_posts. Он позволяет программно изменять параметры WP_Query, что открывает массу возможностей для кастомизации сайта: фильтрация по пользовательским полям, изменение сортировки, исключение или добавление определённых записей и многое другое.
Что такое хук pre_get_posts и где он применяется
Хук pre_get_posts срабатывает сразу после создания объекта WP_Query, но ещё до выполнения SQL-запроса к базе данных. Это значит, что вы можете изменить параметры запроса (аргументы), которые WordPress использует для выборки записей. Благодаря этому меняется содержимое, которое выводится на страницах архива, главной, поиска, а также в пользовательских запросах.
Важно понимать, что pre_get_posts срабатывает для всех WP_Query, включая основной запрос (main query) и дополнительные, созданные вручную. Поэтому нужно грамотно фильтровать, когда и какие изменения применять, чтобы не сломать логику.
Пример типичного применения – изменить количество записей на главной странице, отфильтровать посты по таксономии или метаданным, исключить определённые категории из архива и т.д.
Основные параметры WP_Query, которые можно менять через pre_get_posts
Самые распространённые параметры, которые меняют в pre_get_posts:
post_type— типы записей для выборки (например, 'post', 'page', 'product').posts_per_page— количество записей на страницу.orderbyиorder— сортировка записей.meta_query— фильтрация по метаданным.tax_query— фильтрация по таксономиям (категории, теги и др.).post__not_inиpost__in— исключение или включение конкретных постов по ID.
Используя эти параметры, можно гибко управлять выборкой записей без необходимости писать собственные SQL-запросы.
Как правильно использовать хук pre_get_posts: практические советы
Чтобы избежать ошибок и конфликтов, придерживайтесь следующих правил:
- Проверяйте, что вы меняете именно основной запрос или нужный вам дополнительный запрос. Для основного запроса используйте проверку
$query->is_main_query(). - Не забывайте проверять контекст, например,
is_home(),is_archive(),is_search()и другие условные теги, чтобы применять изменения только там, где нужно. - Для изменения запросов в админке проверяйте
is_admin()и избегайте вмешательства, если это не требуется. - Пишите читаемый и поддерживаемый код, добавляя комментарии и логику в отдельные функции.
Пример 1: Изменение количества записей на главной странице
Допустим, нужно вывести на главной странице не стандартные 10 записей, а 5.
add_action('pre_get_posts', 'wpassist_pre_get_posts_home_posts_count');
function wpassist_pre_get_posts_home_posts_count($query) {
if (!is_admin() && $query->is_main_query() && $query->is_home()) {
$query->set('posts_per_page', 5);
}
}В этом коде проверяем, что это не админка, что запрос основной, и что мы на главной странице, после чего меняем параметр posts_per_page.
Пример 2: Фильтрация записей по произвольному метаполю
Допустим, у нас есть метаполе event_date с датой события, и нужно выводить только будущие события.
add_action('pre_get_posts', 'wpassist_filter_future_events');
function wpassist_filter_future_events($query) {
if (!is_admin() && $query->is_main_query() && is_post_type_archive('event')) {
$meta_query = array(
array(
'key' => 'event_date',
'value' => date('Ymd'),
'compare' => '>=',
'type' => 'NUMERIC'
)
);
$query->set('meta_query', $meta_query);
$query->set('orderby', 'meta_value');
$query->set('meta_key', 'event_date');
$query->set('order', 'ASC');
}
}Здесь мы проверяем, что это архив кастомного типа записи event, и фильтруем по дате, чтобы показывать только события с датой больше или равной сегодняшнему дню. Также сортируем по дате события по возрастанию.
Пример 3: Исключение категории из главной страницы
Если нужно исключить определённую категорию (например, с ID 10) из вывода на главной странице:
add_action('pre_get_posts', 'wpassist_exclude_category_from_home');
function wpassist_exclude_category_from_home($query) {
if (!is_admin() && $query->is_main_query() && $query->is_home()) {
$query->set('cat', '-10'); // минус означает исключение категории
}
}Это простой и эффективный способ убрать из вывода записи из определённой категории.
Как отлаживать изменения в pre_get_posts
Чтобы убедиться, что ваши изменения работают, можете добавить временный вывод параметров запроса:
add_action('pre_get_posts', 'wpassist_debug_pre_get_posts');
function wpassist_debug_pre_get_posts($query) {
if (!is_admin() && $query->is_main_query()) {
error_log('pre_get_posts args: ' . print_r($query->query_vars, true));
}
}Это позволит вам посмотреть в логах сервера, какие параметры передаются в WP_Query, и проверить, были ли внесены ваши изменения.
Полезные плагины для работы с WP_Query и pre_get_posts
Для упрощения работы с запросами и фильтрами можно использовать плагины:
- Query Monitor — показывает подробную информацию о каждом запросе, включая параметры WP_Query, что очень помогает при отладке.
- Admin Columns — позволяет добавлять в админку столбцы с метаданными и таксономиями, что облегчает визуальную работу с записями.
- WP Meta Query Generator — помогает создавать сложные meta_query без написания кода.
Заключение
Хук pre_get_posts — это один из самых мощных инструментов для кастомизации вывода записей в WordPress. Он позволяет программно управлять запросами и создавать уникальный контент без прямого вмешательства в SQL-запросы. Главное — использовать его с умом, чётко понимать контекст и избегать конфликтов с другими плагинами и темами.