Что такое хук pre_get_posts и зачем он нужен
Хук pre_get_posts позволяет изменять главный WP_Query до выполнения SQL-запроса к базе данных. Это мощный инструмент для точечной настройки выборки записей на фронтенде и в административной части. С его помощью можно изменить условия выборки, добавить фильтры, изменить сортировку и многое другое без изменения исходного кода темы или плагина.
Типичные задачи с pre_get_posts
- Исключение определенных категорий из главного цикла
- Показ только определенных типов записей на страницах архива
- Изменение количества записей на странице для конкретного шаблона
- Фильтрация записей по пользовательским метаданным или таксономиям
Диагностика проблемы: почему pre_get_posts не работает
Частая ошибка — хуки не срабатывают, либо изменения не отражаются на сайте. Основные причины:
- Неправильное использование глобального объекта
$query - Изменение не главного запроса (is_main_query())
- Привязка хука на неправильный приоритет или в неподходящем месте (например, слишком рано или поздно)
- Конфликты с другими плагинами или темами
Проверка: добавьте в функцию error_log() или var_dump(), чтобы убедиться, что хук вызывается и что передается нужный объект запроса.
Пошаговое решение: правильное использование pre_get_posts
Рассмотрим пример — исключить из главной страницы записи из категории с ID 10 и изменить количество записей на 5.
function wpdocs_modify_main_query( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
if ( $query->is_home() ) {
// Исключаем категорию с ID 10
$query->set( 'cat', '-10' );
// Устанавливаем количество записей на странице
$query->set( 'posts_per_page', 5 );
}
}
}
add_action( 'pre_get_posts', 'wpdocs_modify_main_query' );Обратите внимание на проверку ! is_admin() и $query->is_main_query() — без них изменения могут примениться к административной панели или к дополнительным запросам.
Другой пример: фильтрация по пользовательскому метаполю
function filter_products_by_meta( $query ) {
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'product' ) ) {
$meta_query = array(
array(
'key' => '_custom_meta_key',
'value' => 'value_to_filter',
'compare' => '='
)
);
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'filter_products_by_meta' );Проверка результата после внедрения
- Обновите главную страницу (или нужный архив) и убедитесь, что записи из категории 10 отсутствуют.
- Проверьте, что на странице выводится ровно 5 записей.
- Используйте Query Monitor или аналогичный плагин для просмотра параметров текущего запроса.
- Для мета-фильтрации убедитесь, что возвращаются только записи с заданным значением метаполя.
Частые ошибки и как их исправить
- Изменения не видны на фронтенде: забыли проверку
$query->is_main_query()или использовали хук слишком рано. - Изменения влияют на админку: не добавили условие
! is_admin(). - Конфликт с другими плагинами: попробуйте отключить остальные плагины и проверить работу вашего кода.
- Неправильные параметры запроса: внимательно проверьте передаваемые в
$query->set()значения, особенно для сложных параметров — таксономии, метазапросы.
Практические советы по использованию pre_get_posts
- Всегда проверяйте
is_main_query(), чтобы не ломать админку и не влиять на дополнительные запросы. - Для сложной логики лучше использовать отдельные функции и четко документировать изменения.
- Тестируйте на разных страницах — главная, архивы, страницы поиска.
- Используйте
WP_Queryилиget_postsдля кастомных запросов, если не хотите менять главный запрос. - Для безопасности и производительности избегайте тяжелых метазапросов без индексации базы.
Сравнение вариантов управления запросами в WordPress
| Метод | Где используется | Плюсы | Минусы |
|---|---|---|---|
| pre_get_posts | Главный WP_Query и дополнительные запросы | Гибкое изменение условий выборки без перезапуска запроса | Можно нарушить логику, если нет проверок |
| WP_Query | Кастомные запросы в шаблонах и плагинах | Полный контроль, не влияет на главный запрос | Дублирование запросов, возможное снижение производительности |
| get_posts | Простые выборки, мелкие запросы | Простота использования, возвращает массив объектов | Меньше контроля, не подходит для сложных фильтров |