wpurok.ru wordpress WPUrok

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

Диагностика задачи: зачем фильтровать товары WooCommerce через pre_get_posts

В стандартном WooCommerce фильтрация товаров обычно осуществляется через встроенные виджеты или параметры URL, например, по категориям или атрибутам. Однако, иногда требуется более тонкая кастомизация выборки товаров — например, исключить определённые товары из каталога, изменить порядок сортировки по условию или добавить условия выборки на нестандартных страницах.

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

Как правильно использовать pre_get_posts для WooCommerce

Пошаговое решение

  1. Подключитесь к хуку pre_get_posts в файле functions.php вашей темы или в отдельном плагине.
  2. Проверьте, что запрос основной ($query->is_main_query()) и что мы находимся на нужной странице WooCommerce (например, архив товаров).
  3. Добавьте условия выборки через методы set объекта $query.
add_action('pre_get_posts', 'custom_woocommerce_product_filter');
function custom_woocommerce_product_filter($query) {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    // Пример: фильтруем только на странице магазина WooCommerce
    if (is_post_type_archive('product') || is_tax('product_cat')) {
        // Исключаем товары с ID 10 и 20
        $query->set('post__not_in', array(10, 20));

        // Устанавливаем сортировку по цене по возрастанию
        $query->set('meta_key', '_price');
        $query->set('orderby', 'meta_value_num');
        $query->set('order', 'ASC');

        // Можно добавить дополнительные параметры, например, выводить только товары со статусом 'instock'
        $meta_query = $query->get('meta_query');
        if (!is_array($meta_query)) {
            $meta_query = [];
        }
        $meta_query[] = [
            'key' => '_stock_status',
            'value' => 'instock'
        ];
        $query->set('meta_query', $meta_query);
    }
}

Как проверить, что фильтр сработал

  • Откройте страницу магазина WooCommerce (например, /shop/).
  • Проверьте, что товары с ID 10 и 20 отсутствуют в списке.
  • Убедитесь, что товары отображаются в порядке возрастания цены.
  • Проверьте статус товара в админке — должны отображаться только товары со статусом «В наличии».

Расширенные сценарии фильтрации товаров

Фильтрация по пользовательским полям и атрибутам

Для фильтрации по атрибутам или произвольным полям используйте мета-запросы (meta_query) или таксономии (tax_query).

add_action('pre_get_posts', 'filter_products_by_attribute');
function filter_products_by_attribute($query) {
    if (is_admin() || !$query->is_main_query()) {
        return;
    }

    if (is_post_type_archive('product')) {
        $tax_query = $query->get('tax_query');
        if (!is_array($tax_query)) {
            $tax_query = [];
        }

        $tax_query[] = [
            'taxonomy' => 'pa_color', // таксономия атрибута, например цвет
            'field'    => 'slug',
            'terms'    => 'red', // фильтруем по красному цвету
            'operator' => 'IN',
        ];

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

Чек-лист: как правильно реализовать фильтрацию через pre_get_posts

  • Подключайтесь только к основному запросу (is_main_query()).
  • Не вмешивайтесь в административную часть (is_admin()).
  • Правильно определяйте условия страниц (is_post_type_archive('product'), is_tax()).
  • Используйте set для изменения параметров запроса.
  • Для мета-полей применяйте meta_query, для атрибутов — tax_query.
  • Проверяйте результат на фронтенде, чтобы убедиться, что фильтрация работает.

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

Ошибка 1: фильтр не работает, товары не меняются

Причина: условие is_main_query() или is_post_type_archive('product') не срабатывает. Обычно это из-за того, что фильтр подключён слишком рано или используется на неправильной странице.

Решение: убедитесь, что хук pre_get_posts подключён к действию add_action('pre_get_posts', ...), и что проверка условий корректна.

Ошибка 2: фильтрация ломает пагинацию

Причина: изменение параметров запроса без учёта пагинации.

Решение: не меняйте параметры posts_per_page без необходимости и проверьте, что paged передаётся в запрос.

Ошибка 3: конфликт с другими плагинами WooCommerce

Причина: другие плагины тоже изменяют pre_get_posts и перезаписывают параметры.

Решение: используйте приоритеты в add_action, например add_action('pre_get_posts', 'your_func', 20), чтобы контролировать порядок выполнения.

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

  • Не выполняйте тяжелые запросы или сложные вычисления внутри pre_get_posts, чтобы не замедлять загрузку страниц.
  • При фильтрации по мета-полям убедитесь, что соответствующие поля индексированы в базе данных для ускорения запросов.
  • Используйте кэширование страниц и объектов (например, Object Cache) для снижения нагрузки при сложных фильтрах.
  • Тестируйте изменения на тестовом сервере перед выкатыванием на продакшн.

Сравнение подходов к фильтрации товаров WooCommerce

МетодПреимуществаНедостатки
pre_get_postsГибкость, изменение основного запроса, высокая производительностьТребует знаний WP_Query, можно сломать пагинацию
WP_Query с новым запросомИзолированность, не влияет на основной запросДополнительные ресурсы, дублирование кода
Shortcode с кастомным выводомПростота вставки в контентНе меняет страницы архива, может влиять на SEO
×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее