Как использовать хук pre_get_posts для кастомных фильтров в WooCommerce

Диагностика проблемы: почему стандартные фильтры WooCommerce не всегда подходят

WooCommerce предлагает базовые фильтры каталога товаров, но часто возникает необходимость создать собственные фильтры по произвольным параметрам (например, по метаполям, пользовательским таксономиям или сложным условиям). Попытка модифицировать запрос без правильного использования pre_get_posts может привести к неисправностям: фильтры не срабатывают, страница товаров выводит пустой результат или нарушается пагинация.

Пошаговое решение: добавляем кастомные фильтры через pre_get_posts

1. Определяем место для кода

Лучше всего добавить код в файл functions.php вашей дочерней темы или в отдельный плагин для кастомных функций.

2. Проверяем, что запрос именно для главной страницы магазина

function custom_woocommerce_filter_query( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
        // Здесь добавим логику фильтрации
    }
}
add_action( 'pre_get_posts', 'custom_woocommerce_filter_query' );

3. Добавляем фильтр по произвольному метаполю

Допустим, у товаров есть метаполе _custom_color, по которому надо фильтровать.

function custom_woocommerce_filter_query( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
        if ( ! empty( $_GET['filter_color'] ) ) {
            $meta_query = array(
                array(
                    'key'     => '_custom_color',
                    'value'   => sanitize_text_field( wp_unslash( $_GET['filter_color'] ) ),
                    'compare' => '=',
                ),
            );

            $query->set( 'meta_query', $meta_query );
        }
    }
}
add_action( 'pre_get_posts', 'custom_woocommerce_filter_query' );

4. Обрабатываем фильтр по пользовательской таксономии

Если в WooCommerce добавлена своя таксономия, например product_brand, фильтр можно добавить так:

function custom_woocommerce_filter_query( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
        $tax_query = array();

        if ( ! empty( $_GET['filter_brand'] ) ) {
            $tax_query[] = array(
                'taxonomy' => 'product_brand',
                'field'    => 'slug',
                'terms'    => sanitize_text_field( wp_unslash( $_GET['filter_brand'] ) ),
            );
        }

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

5. Объединяем несколько условий

Можно комбинировать meta_query и tax_query, добавляя несколько условий:

function custom_woocommerce_filter_query( $query ) {
    if ( is_admin() || ! $query->is_main_query() ) {
        return;
    }

    if ( is_post_type_archive( 'product' ) || is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
        $meta_query = array();
        $tax_query = array();

        if ( ! empty( $_GET['filter_color'] ) ) {
            $meta_query[] = array(
                'key'     => '_custom_color',
                'value'   => sanitize_text_field( wp_unslash( $_GET['filter_color'] ) ),
                'compare' => '=',
            );
        }

        if ( ! empty( $_GET['filter_brand'] ) ) {
            $tax_query[] = array(
                'taxonomy' => 'product_brand',
                'field'    => 'slug',
                'terms'    => sanitize_text_field( wp_unslash( $_GET['filter_brand'] ) ),
            );
        }

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

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

Проверка результата после внедрения

  • Откройте страницу магазина или категорий товаров.
  • Добавьте в URL параметры фильтра, например: ?filter_color=red&filter_brand=nike.
  • Проверьте, что список товаров изменился согласно фильтрам.
  • Убедитесь, что пагинация и сортировка работают корректно.
  • Проверьте, что в админке (редакторе запросов) нет ошибок.

Частые ошибки и как их исправить

  • Фильтр не срабатывает — возможно, не проверяется $query->is_main_query(). Убедитесь, что код внутри блока для основного запроса.
  • Пагинация ломается — если меняете параметры запроса, не забудьте, что posts_per_page и другие параметры должны сохраняться или корректно переустанавливаться.
  • Пустой результат — проверьте правильность ключей метаполей и значений фильтров, используйте var_dump($query->query_vars) для отладки.
  • Фильтр не применяется на страницах архива — проверьте условия is_post_type_archive и is_tax, возможно, нужно расширить список проверок.

Практические советы по безопасности и производительности

  • Всегда используйте sanitize_text_field и wp_unslash для очистки входящих данных из $_GET.
  • Избегайте тяжелых запросов с большим числом meta_query, они сильно влияют на производительность БД.
  • При необходимости кешируйте результаты фильтрации с помощью transient API или внешних кешей.
  • Если фильтров много, подумайте о реализации AJAX-фильтров, чтобы уменьшить нагрузку и улучшить UX.

Сравнение способов фильтрации в WooCommerce

МетодПлюсыМинусыКогда использовать
Стандартные фильтры WooCommerceПростота, интеграция с шаблонамиОграниченные возможности кастомизацииБазовые фильтры по категориям и атрибутам
Хук pre_get_posts с meta_query и tax_queryГибкость, точечная настройкаСложность, возможные проблемы с производительностьюКастомные фильтры по метаполям и таксономиям
Плагины фильтров (например, FacetWP, Filter Everything)Быстрая реализация, готовые UIЗависимость от стороннего кода, платные версииЕсли нет ресурсов на кастомную разработку
Как создать собственный REST API endpoint в WordPress с примером кода
31.12.2025
Создание подробного лога ошибок в WordPress для эффективной отладки
31.03.2026
Как создать адаптивный велосипедный каталог на WordPress с фильтрами и сортировкой
27.12.2025
Руководство по созданию пользовательских типов записей в WordPress
19.11.2025
Как добавить автоматическое обновление тем и плагинов в WordPress без рисков
05.04.2026