Что такое хук pre_get_posts и зачем он нужен
Хук pre_get_posts позволяет изменять параметры основного запроса WordPress до того, как он выполнится. Это мощный инструмент для автоматизации выборки записей на фронтенде и в админке без дублирования кода и создания новых WP_Query.
С помощью этого хука можно динамически фильтровать, сортировать и ограничивать записи по любым параметрам — так можно гибко адаптировать вывод контента под конкретные задачи без плагинов.
Диагностика: как понять, что нужно использовать pre_get_posts
Частые ситуации для применения:
- Нужно изменить главную страницу (home) или архивы категорий/меток без создания дополнительного шаблона.
- Требуется исключить или добавить записи в стандартный список постов.
- Необходимо менять количество записей на странице без плагинов.
- Хотите автоматически сортировать записи по кастомному полю или дате.
Если сейчас вы создаёте отдельные WP_Query или фильтруете контент вручную, скорее всего, pre_get_posts поможет упростить код и повысить производительность.
Пошаговое решение: пример автоматической фильтрации и сортировки записей
Рассмотрим задачу: на главной странице сайта выводить только записи из категории с ID 5, сортировать по убыванию даты публикации и показывать по 10 записей.
Добавьте следующий код в файл темы functions.php или в кастомный плагин:
function wptest_modify_main_query(\WP_Query $query) {
// Проверяем, что это главный запрос и фронтенд, чтобы не сломать админку
if ( ! is_admin() && $query->is_main_query() ) {
// Фильтруем главную страницу
if ( $query->is_home() ) {
// Показываем только записи из категории с ID 5
$query->set('cat', 5);
// Сортируем по дате публикации DESC
$query->set('orderby', 'date');
$query->set('order', 'DESC');
// Ограничиваем количество записей на странице
$query->set('posts_per_page', 10);
}
}
}
add_action('pre_get_posts', 'wptest_modify_main_query');Этот код корректно изменит запрос главной страницы без создания новых запросов и без влияния на админку или другие запросы.
Расширение: фильтрация на страницах архивов
Чтобы настроить похожее поведение для архивов категорий, например, исключить из вывода записи с меткой «скрытый», добавьте в тот же хук:
if ( $query->is_category() ) {
$tax_query = array(
array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => 'skrytyj',
'operator' => 'NOT IN',
),
);
$query->set( 'tax_query', $tax_query );
}Как проверить, что решение сработало
- Откройте главную страницу сайта — должны отображаться только посты из категории с ID 5, отсортированные по дате.
- Если есть доступ к базе, выполните SQL-запрос для проверки количества постов и категории — они должны совпадать с фильтрацией.
- Включите режим отладки и добавьте в код временный вывод параметров запроса через
var_dump($query->query_vars);— убедитесь, что параметры установлены. - Проверьте, что в админке не изменился список записей и нет ошибок.
Частые ошибки при работе с pre_get_posts и как их исправить
- Изменение запроса в админке: если не добавить проверку
!is_admin(), параметры запроса изменятся и в панели, что сломает логику. Обязательно проверяйте, что вы на фронтенде. - Не учитывать главный запрос: без проверки
$query->is_main_query()изменения могут применяться к дополнительным запросам, вызывая непредсказуемое поведение. - Дублирование параметров: если одновременно создаются новые WP_Query и меняется главный запрос, может быть конфликт. Лучше выбрать один подход.
- Неправильные параметры: например, неверный синтаксис для
tax_queryилиcat. Используйте официальную документацию для справки.
Практические советы по производительности и безопасности
- Избегайте тяжелых запросов с большим количеством условий в
pre_get_posts, так как это влияет на скорость генерации страниц. - Если нужно сложное фильтрование, рассмотрите возможность кеширования результата с помощью Transients API.
- Не используйте
pre_get_postsдля массового изменения запросов в админке — для этого лучше создавать отдельные WP_Query. - Всегда тестируйте изменения на тестовом окружении, чтобы не сломать фронтенд и админку.
Сравнение вариантов реализации автоматизации выборок
| Подход | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| pre_get_posts | Изменяет основной запрос, нет дублирования, легко масштабируется | Можно случайно повлиять на админку, требует осторожности | Изменение вывода на фронтенде без кастомных WP_Query |
| Создание нового WP_Query | Полный контроль над выборкой, не влияет на основной запрос | Дублирование кода, возможные конфликты с пагинацией | Вывод дополнительного контента, кастомные блоки |
| Использование плагинов фильтрации | Простота настройки, готовые интерфейсы | Может быть избыточно, нагрузка на сайт, сложность кастомизации | Быстрые решения без программирования |