Диагностика задачи: почему нужно исключать товары по атрибутам
В интернет-магазинах на WooCommerce иногда требуется скрыть из каталога определенные товары по заданным атрибутам. Например, товары с атрибутом "Сезон" со значением "Зима" в летний период, или товары с определенным цветом или размером, которые временно не продаются.
Стандартными средствами WooCommerce скрыть товары по атрибутам в каталоге нельзя — нужно писать кастомный код, который модифицирует запрос WP_Query.
Как проверить, что товары с нужным атрибутом отображаются
Для диагностики можно использовать простой WP_Query, чтобы отобразить товары с нужным атрибутом:
$args = [
'post_type' => 'product',
'tax_query' => [
[
'taxonomy' => 'pa_season', // таксономия атрибута
'field' => 'slug',
'terms' => 'zima',
'operator' => 'IN',
],
],
];
$query = new WP_Query($args);
if($query->have_posts()) {
while($query->have_posts()) {
$query->the_post();
echo get_the_title() . '<br>';
}
} else {
echo 'Товары не найдены';
}
wp_reset_postdata();
Если товары выводятся, значит атрибуты корректно присвоены и можно переходить к исключению из каталога.
Пошаговое решение: исключение товаров по атрибутам из каталога WooCommerce
1. Определяем таксономию атрибута
Атрибуты товаров в WooCommerce хранятся в таксономиях с префиксом pa_. Например, атрибут "Сезон" будет таксономией pa_season. Можно убедиться через админку или функцию get_object_taxonomies('product').
2. Подключаем фильтр woocommerce_product_query
Для изменения основного запроса каталога добавим фильтр в functions.php темы или в кастомный плагин:
add_action('woocommerce_product_query', 'exclude_products_by_attribute_from_catalog');
function exclude_products_by_attribute_from_catalog($q) {
$tax_query = $q->get('tax_query');
if (!is_array($tax_query)) {
$tax_query = [];
}
$tax_query[] = [
'taxonomy' => 'pa_season', // измените на вашу таксономию
'field' => 'slug',
'terms' => ['zima'], // значения атрибута, которые нужно исключить
'operator' => 'NOT IN',
];
$q->set('tax_query', $tax_query);
}
3. Проверяем, что исключение сработало
Переходим на страницу магазина или категорию. Товары с атрибутом "zima" должны исчезнуть из списка.
Обязательно очистите кеш сайта и браузера, если используется кеширование.
Проверка результата после внедрения
- Откройте страницу магазина (Shop) или категорию товаров.
- Убедитесь, что товары с исключаемым атрибутом не отображаются.
- Если у вас включена сортировка и фильтры, проверьте, что товары не появляются по ним.
- Запустите тестовый WP_Query с атрибутом, чтобы убедиться, что товары есть в базе, но скрыты из каталога.
Частые ошибки и как исправить
- Неправильное имя таксономии атрибута: часто путают с названием атрибута. В WooCommerce атрибуты — это таксономии с префиксом
pa_. Проверьте имя через админку или функциюget_object_taxonomies('product'). - Неочищенный кеш: если используете кеширование (Redis, WP Super Cache, LiteSpeed), нужно очистить его после внесения изменений.
- Изменения применяются не в том месте: фильтр
woocommerce_product_queryвлияет только на основные запросы WooCommerce. Если вы показываете товары через кастомные запросы, нужно изменять их отдельно. - Неправильный оператор в tax_query: для исключения нужно использовать
'operator' => 'NOT IN', а неIN.
Практические советы по производительности
- Добавляйте фильтр
woocommerce_product_queryтолько еслиis_shop()илиis_product_category(), чтобы не нагружать запросы везде:
add_action('woocommerce_product_query', 'exclude_products_by_attribute_from_catalog');
function exclude_products_by_attribute_from_catalog($q) {
if (!is_shop() && !is_product_category()) {
return;
}
$tax_query = $q->get('tax_query');
if (!is_array($tax_query)) {
$tax_query = [];
}
$tax_query[] = [
'taxonomy' => 'pa_season',
'field' => 'slug',
'terms' => ['zima'],
'operator' => 'NOT IN',
];
$q->set('tax_query', $tax_query);
}
- Проверяйте нагрузку SQL-запросов на больших каталогах, чтобы избежать замедления.
- Если нужно скрыть товары по нескольким атрибутам, объединяйте условия в
tax_queryс правильнымrelation(ANDилиOR).
Сравнение вариантов решения
| Метод | Плагин | Код | Компромисс |
|---|---|---|---|
| Исключение по атрибутам | Плагины фильтрации (например, WooCommerce Product Filter) | Фильтр woocommerce_product_query с tax_query | Плагины удобны для непрофи, но могут влиять на производительность и не всегда гибко |
| Производительность | Плагины могут нагружать базу | Код работает напрямую, минимальный оверхед при правильной реализации | Требует знаний PHP и WooCommerce API |