Что такое хук pre_get_posts и зачем он нужен
Хук pre_get_posts позволяет изменить основной запрос WordPress до его выполнения. Это самый удобный способ программно фильтровать или модифицировать выборку постов, не прибегая к дополнительным запросам или сложным обходным путям.
На практике он полезен для изменения вывода архивных страниц, главной, поиска, а также для кастомных запросов в админке.
Диагностика проблемы: почему стандартные фильтры не работают
Часто новички пытаются менять выборку через query_posts() или создают новые WP_Query, что приводит к дублированию запросов, пагинации и другим ошибкам. Если вы хотите влиять на основной запрос, необходимо использовать pre_get_posts.
Типичные симптомы неправильного подхода:
- Пагинация ломается или не работает
- Выводятся не те записи, что ожидались
- Конфликты с другими плагинами или темой
Пошаговое решение: фильтрация записей с помощью pre_get_posts
Пример: показывать на главной только посты определённой категории
function wpboot_filter_home_category( \WP_Query $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_home() ) {
$query->set( 'cat', '5' ); // ID категории 5
}
}
add_action( 'pre_get_posts', 'wpboot_filter_home_category' );В этом примере на главной странице будут выводиться только записи категории с ID 5.
Пример: исключить определённые категории из архива блога
function wpboot_exclude_category_from_archive( \WP_Query $query ) {
if ( ! is_admin() && $query->is_main_query() && $query->is_archive() ) {
$query->set( 'category__not_in', array( 7, 9 ) ); // исключаем категории 7 и 9
}
}
add_action( 'pre_get_posts', 'wpboot_exclude_category_from_archive' );Как проверить, что фильтрация сработала
- Очистите кэш сайта и браузера перед тестом
- Перейдите на нужную страницу (например, главная или архив)
- Убедитесь, что выводятся только нужные записи (например, только из категории 5)
- Проверьте пагинацию — она должна работать корректно
- Можно вывести отладочную информацию через
error_log(print_r($query, true))или временно добавитьvar_dump($query->query_vars)в шаблон
Частые ошибки при работе с pre_get_posts
- Отсутствие проверки
is_main_query()— приводит к изменению всех запросов, включая админские и сторонние WP_Query - Игнорирование условий страницы — нужно проверять
is_home(),is_archive(),is_search()и другие, иначе изменения применятся везде - Использование
query_posts()вместе с pre_get_posts — вызывает конфликты и нарушения пагинации - Неправильный формат параметров — например, для исключения категорий нужен массив, а не строка
Практические советы по безопасности и производительности
- Используйте
pre_get_postsтолько для изменения основного запроса, не создавайте новых запросов внутри этого хука - Добавляйте условия, чтобы не влиять на админку и REST API (например,
if ( is_admin() ) return;) - Для сложных фильтров избегайте больших массивов в параметрах, используйте кэширование результатов, если запросы тяжелые
- Проверяйте совместимость с плагинами, которые тоже могут использовать
pre_get_posts
Сравнение вариантов изменения выборки записей
| Метод | Плюсы | Минусы |
|---|---|---|
| Использование pre_get_posts | Изменяет основной запрос корректно, поддерживается WP, пагинация работает | Требует понимания условий запроса, может конфликтовать при неправильном использовании |
| query_posts() | Простой вызов, быстрое тестирование | Перезаписывает основной запрос, ломает пагинацию, не рекомендуется |
| Создание нового WP_Query | Гибкость, используется для дополнительных запросов | Не влияет на основной вывод, пагинация отдельно |