Как использовать метод pre_get_posts для создания сложного фильтрования в WordPress

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

Что такое pre_get_posts и зачем его использовать для фильтров

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

Например, если вам нужно реализовать сложные фильтры по нескольким таксономиям и метаполям, или исключить из выборки определённые записи, вы можете сделать это централизованно через этот хук.

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

Пример: создание сложного AJAX-фильтра с таксономиями и метаполями

Рассмотрим практический пример, как с помощью pre_get_posts реализовать фильтр записей по нескольким параметрам — категориям, тегам и кастомному метаполю «цена».

Для начала добавим обработчик в functions.php вашей темы или плагина:

function wplessons_pre_get_posts_filter(\WP_Query $query) {
    // Проверяем, что это не админка и основной запрос
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    // Пример: применяем фильтр только на главной странице архива записей
    if (is_post_type_archive('post') || is_home()) {
        $tax_query = [];
        $meta_query = [];

        // Фильтр по категориям, переданным в URL, например ?cat_filter=5,7
        if (!empty($_GET['cat_filter'])) {
            $cats = array_map('intval', explode(',', $_GET['cat_filter']));
            $tax_query[] = [
                'taxonomy' => 'category',
                'field'    => 'term_id',
                'terms'    => $cats,
                'operator' => 'IN',
            ];
        }

        // Фильтр по тегам, например ?tag_filter=wordpress,php
        if (!empty($_GET['tag_filter'])) {
            $tags = array_map('sanitize_text_field', explode(',', $_GET['tag_filter']));
            $tax_query[] = [
                'taxonomy' => 'post_tag',
                'field'    => 'slug',
                'terms'    => $tags,
                'operator' => 'IN',
            ];
        }

        // Фильтр по метаполю 'price', например ?price_min=100&price_max=500
        $price_min = isset($_GET['price_min']) ? (float)$_GET['price_min'] : 0;
        $price_max = isset($_GET['price_max']) ? (float)$_GET['price_max'] : 0;
        if ($price_min || $price_max) {
            $meta_query[] = [
                'key'     => 'price',
                'value'   => [$price_min, $price_max],
                'compare' => 'BETWEEN',
                'type'    => 'NUMERIC',
            ];
        }

        if ($tax_query) {
            $query->set('tax_query', $tax_query);
        }

        if ($meta_query) {
            $query->set('meta_query', $meta_query);
        }

        // Дополнительные настройки сортировки
        if (!empty($_GET['orderby'])) {
            $orderby = sanitize_text_field($_GET['orderby']);
            if ($orderby === 'price') {
                $query->set('orderby', 'meta_value_num');
                $query->set('meta_key', 'price');
                $query->set('order', 'ASC');
            } elseif ($orderby === 'date') {
                $query->set('orderby', 'date');
                $query->set('order', 'DESC');
            }
        }
    }
}
add_action('pre_get_posts', 'wplessons_pre_get_posts_filter');

В этом коде мы строим два массива tax_query и meta_query в зависимости от параметров GET, переданных в URL. Это позволяет динамически менять выборку без создания дополнительных WP_Query.

Пояснение к параметрам фильтрации

  • cat_filter — список ID категорий, по которым нужно отфильтровать посты
  • tag_filter — список слуг тегов для фильтрации
  • price_min и price_max — диапазон для числового метаполя «price»
  • orderby — сортировка по цене или дате

Как использовать фильтр на фронтенде с AJAX

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

Например, используя jQuery, можно сделать примерно так:

jQuery(document).ready(function($) {
    $('#filter-form').on('change', 'select, input', function() {
        var data = $('#filter-form').serialize();
        $.ajax({
            url: window.location.href,
            data: data,
            type: 'GET',
            success: function(response) {
                var newContent = $(response).find('#posts-container').html();
                $('#posts-container').html(newContent);
            }
        });
    });
});

Здесь #filter-form — форма с фильтрами, а #posts-container — контейнер с выводом записей. AJAX-запрос обновляет этот блок без полной перезагрузки.

Оптимизация и тонкости работы с pre_get_posts

Несмотря на мощь pre_get_posts, важно помнить о нескольких моментах:

  • Обязательно проверяйте is_main_query(), чтобы не менять запросы в админке или вспомогательные WP_Query.
  • Если используете tax_query и meta_query — помните, что их сложные комбинации могут замедлить запросы. Важно тестировать производительность.
  • Для сложных фильтров с большим количеством параметров стоит рассмотреть кэширование результатов или использование плагинов оптимизации.

Также для визуализации фильтров на сайте можно использовать специализированные плагины, например, ABC Pagination — отличный инструмент для улучшения навигации по фильтрованным постам.

Заключение

Использование pre_get_posts — это самый правильный способ реализовать сложное фильтрование записей в WordPress без прямого вмешательства в SQL-запросы. Применяйте проверку условий, комбинируйте таксономии и метаполя, и не забывайте про оптимизацию.

Если хотите автоматизировать создание контента с фильтрами или улучшить UX, обратите внимание на плагины из каталога WPSHOP, которые помогут сделать ваш сайт ещё удобнее и функциональнее.

Как настроить OTP в формах WordPress для повышения безопасности
29.03.2026
Как удалить автоматические частые запросы в WordPress для оптимизации производительности
19.01.2026
Автоматическое удаление товаров из заказов WooCommerce после отмены или возврата
26.06.2026
Как избежать ошибок при массовом изменении статусов заказов WooCommerce
23.06.2026
Автоматическое удаление товаров из заказов WooCommerce после отмены или возврата
05.06.2026