Диагностика проблемы: почему фильтры WooCommerce не работают корректно
Часто при кастомизации WooCommerce возникает ситуация, когда стандартные фильтры (например, по категориям, атрибутам или цене) перестают корректно работать. Это проявляется в том, что при выборе фильтра страница либо не обновляется, либо выводит некорректный список товаров. Основная причина — конфликт с другими запросами WordPress или неправильная модификация основного запроса (main query) без учёта особенностей WooCommerce.
Пошаговое решение с использованием хука pre_get_posts
1. Определяем, когда применять фильтр
В хук pre_get_posts попадают все запросы WordPress. Нам нужно ограничить изменения только для главного запроса на странице магазина или архиве товаров.
function hueman_modify_woocommerce_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'product' ) || is_tax( array( 'product_cat', 'product_tag' ) ) ) {
// Здесь добавляем нашу логику
}
}
add_action( 'pre_get_posts', 'hueman_modify_woocommerce_query' );2. Добавляем фильтрацию по кастомным параметрам (пример: скрыть товары без цены)
function hueman_modify_woocommerce_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'product' ) || is_tax( array( 'product_cat', 'product_tag' ) ) ) {
$meta_query = $query->get( 'meta_query' );
if ( ! $meta_query ) {
$meta_query = array();
}
$meta_query[] = array(
'key' => '_price',
'value' => 0,
'compare' => '>',
'type' => 'NUMERIC',
);
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'hueman_modify_woocommerce_query' );3. Используем для исправления конфликтов с пагинацией и сортировкой
Если после добавления фильтра пагинация работает неправильно, и показываются все товары, необходимо установить правильный параметр posts_per_page и убедиться, что сортировка не сбрасывается:
function hueman_modify_woocommerce_query( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( is_post_type_archive( 'product' ) || is_tax( array( 'product_cat', 'product_tag' ) ) ) {
$query->set( 'posts_per_page', 12 ); // Установить нужное количество товаров на страницу
// Не сбрасываем orderby, если он уже есть
if ( ! $query->get( 'orderby' ) ) {
$query->set( 'orderby', 'date' );
$query->set( 'order', 'DESC' );
}
// Добавляем фильтрацию по цене, как в предыдущем примере
$meta_query = $query->get( 'meta_query' );
if ( ! $meta_query ) {
$meta_query = array();
}
$meta_query[] = array(
'key' => '_price',
'value' => 0,
'compare' => '>',
'type' => 'NUMERIC',
);
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'hueman_modify_woocommerce_query' );Проверка результата после внедрения
- Перейдите на страницу магазина WooCommerce или архив категории товаров.
- Убедитесь, что товары без цены не отображаются.
- Проверьте пагинацию: количество товаров на странице соответствует заданному (
posts_per_page), переход между страницами работает корректно. - Проверьте сортировку товаров — по умолчанию по дате (новые первыми) или по вашему заданию.
Частые ошибки и как их исправить
- Изменения влияют на админку: не забудьте проверять
is_admin(), чтобы не ломать админские запросы. - Модифицируется не основной запрос: всегда проверяйте
$query->is_main_query(), иначе можете изменить дополнительные запросы (виджеты, сайдбары). - Пагинация сбивается: при установке фильтров убедитесь, что не сбрасываете параметры
posts_per_page,orderbyиpaged. - Неправильные условия для страницы магазина: используйте
is_post_type_archive('product')и таксономииis_tax(['product_cat','product_tag']), чтобы не влиять на другие разделы сайта.
Практические советы по производительности и безопасности
- При добавлении
meta_queryизбегайте избыточных условий, так как это влияет на скорость запросов к базе. - Кэшируйте результаты для сложных фильтров с использованием Object Cache или плагинов кэширования.
- Используйте проверку nonce и права пользователя, если фильтры зависят от пользовательских параметров.
Сравнение способов реализации фильтрации WooCommerce с помощью pre_get_posts
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Использование pre_get_posts | Гибкость, полный контроль над запросом | Требует понимания WP_Query, легко сломать пагинацию | Тщательная проверка условий и параметров запроса |
| Плагины WooCommerce фильтрации | Простота использования, готовый UI | Может замедлять сайт, ограниченная кастомизация | Использовать для простых случаев, при сложной логике — pre_get_posts |
| Кастомные SQL-запросы | Максимальная производительность при правильной реализации | Сложность поддержки и риски безопасности | Использовать только при необходимости, с подготовкой запросов |