Как использовать хук pre_get_posts в WordPress для фильтрации записей

В WordPress хук pre_get_posts является мощным инструментом для изменения основного запроса на страницах сайта до того, как он выполнится. Это позволяет гибко фильтровать записи, изменять параметры выборки, исключать определённые записи, категории и многое другое без изменения исходного кода ядра или плагинов.

Что такое хук pre_get_posts и зачем он нужен

Хук pre_get_posts срабатывает перед выполнением запроса WP_Query, который формирует список записей, отображаемых на странице. Используя этот хук, можно изменить параметры запроса — например, изменить количество записей на странице, добавить фильтрацию по меткам, исключить категории или кастомные типы записей.

Это особенно полезно, когда нужно кастомизировать отображение записей на страницах блога, архивов, главной страницы или любых других страницах с выводом списков записей.

Важно: чтобы не повредить запросы админки, нужно обязательно проверять, что код применяется только на фронтенде.

Как правильно использовать хук pre_get_posts для фильтрации записей

Для начала создадим функцию, которая будет изменять параметры основного запроса. Пример ниже показывает, как изменить количество записей на странице блога и исключить из выборки записи из категории с ID 10.

function wplessons_pre_get_posts_filter(\WP_Query $query) {
    // Проверяем, что мы на фронтенде и это главный запрос
    if ( !is_admin() && $query->is_main_query() ) {
        // Изменяем количество записей на странице блога
        if ( $query->is_home() ) {
            $query->set('posts_per_page', 5);
        }
        // Исключаем категорию с ID 10 из выборки
        if ( $query->is_category() ) {
            $query->set('cat', '-' . 10);
        }
    }
}
add_action('pre_get_posts', 'wplessons_pre_get_posts_filter');

В этом примере:

  • !is_admin() — чтобы код не влиял на запросы в административной панели;
  • $query->is_main_query() — чтобы изменить только основной запрос, а не дополнительные WP_Query;
  • $query->is_home() — условие для главной страницы блога;
  • $query->is_category() — условие для страниц архивов по категориям;
  • $query->set() — метод для изменения параметров запроса.

Примеры практического применения pre_get_posts

1. Фильтрация по произвольному полю (метаполю)

Допустим, у вас есть произвольное поле featured, по которому нужно выводить только отмеченные записи на главной странице.

function wplessons_filter_featured_posts(\WP_Query $query) {
    if ( !is_admin() && $query->is_main_query() && $query->is_home() ) {
        $meta_query = array(
            array(
                'key' => 'featured',
                'value' => '1',
                'compare' => '='
            )
        );
        $query->set('meta_query', $meta_query);
    }
}
add_action('pre_get_posts', 'wplessons_filter_featured_posts');

Так вы ограничите вывод главной страницы только записями, где произвольное поле featured равно 1.

2. Исключение кастомных типов записей из архива

Если у вас есть кастомный тип записи portfolio, и вы не хотите, чтобы записи этого типа попали в общий архив блога, используйте следующий код:

function wplessons_exclude_portfolio_from_blog(\WP_Query $query) {
    if ( !is_admin() && $query->is_main_query() && $query->is_home() ) {
        $post_types = $query->get('post_type');
        if (empty($post_types)) {
            $post_types = array('post');
        }
        elseif (!is_array($post_types)) {
            $post_types = array($post_types);
        }
        // Убираем 'portfolio' из массива
        $post_types = array_diff($post_types, array('portfolio'));
        $query->set('post_type', $post_types);
    }
}
add_action('pre_get_posts', 'wplessons_exclude_portfolio_from_blog');

3. Сортировка записей по пользовательскому полю

Иногда нужно отсортировать записи по значению произвольного поля, например, по рейтингу. Пример сортировки по полю rating по убыванию:

function wplessons_sort_by_rating(\WP_Query $query) {
    if ( !is_admin() && $query->is_main_query() && $query->is_home() ) {
        $query->set('meta_key', 'rating');
        $query->set('orderby', 'meta_value_num');
        $query->set('order', 'DESC');
    }
}
add_action('pre_get_posts', 'wplessons_sort_by_rating');

Советы по работе с pre_get_posts и оптимизация

Работа с pre_get_posts требует аккуратности, чтобы не нарушить отображение сайта и не снизить производительность. Вот несколько рекомендаций:

  • Всегда проверяйте, что вы меняете только главный запрос на фронтенде. Это предотвращает нежелательные эффекты в админке и в дополнительных WP_Query.
  • Используйте точные условия. Например, is_home(), is_category(), is_post_type_archive() и другие условные теги помогут влиять только на нужные страницы.
  • Не перегружайте запрос сложными мета-запросами без необходимости. Они могут сильно замедлить сайт, особенно на больших базах данных.
  • Для сложных фильтров рассмотрите использование специализированных плагинов. Например, плагин Clearfy Pro помогает оптимизировать и управлять запросами.

Заключение

Хук pre_get_posts — это универсальный инструмент для разработки и кастомизации WordPress. Он позволяет вмешиваться в формирование запросов и менять логику вывода записей без правки шаблонов или плагинов. Освоив его, вы получите мощный механизм для решения множества задач по фильтрации, сортировке и оптимизации контента.

Для более глубокого понимания и практического применения можно изучить документацию WordPress и примеры на официальном сайте.

Как создать автоматическое удаление старого контента в WordPress
02.04.2026
Как использовать фильтры WP_Query для комплексного поиска в WordPress
22.03.2026
Как отключить автовыделение и автозагрузку изображений в WordPress
02.04.2026
Как добавить OTP (одноразовый пароль) в формы WordPress для повышения безопасности
22.02.2026
Автоматическое удаление товаров из заказов WooCommerce после отмены или возврата
28.05.2026