Диагностика задачи: зачем и когда нужно исключать товары по атрибуту
В WooCommerce часто возникает необходимость скрыть из каталога или поиска определённые товары или их варианты, основываясь на значениях атрибутов. Например, исключить все товары с атрибутом "Сезон" = "Зима" или скрыть варианты с атрибутом "Цвет" = "Красный".
Такая задача полезна для сезонных распродаж, ограничений по складу, маркетинговых акций или для упрощения интерфейса магазина. Но WooCommerce не предлагает готовых опций для фильтрации по атрибутам на уровне вывода товаров, поэтому приходится использовать код.
Как проверить, что товары или варианты нужно исключить
- Определите точный slug атрибута (например, pa_sezon для атрибута "Сезон").
- Определите slug или id значения атрибута, которое нужно исключить (например, "zima").
- Проверьте, что товары/варианты с этими атрибутами действительно отображаются в каталоге или поиске.
Пошаговое решение: исключаем товары и варианты по атрибуту через код
1. Исключение товаров с заданным атрибутом из каталога и поиска
Добавьте следующий код в functions.php вашей темы (рекомендуется дочерняя тема) или в пользовательский плагин:
add_action('pre_get_posts', 'wpreg_exclude_products_by_attribute');
function wpreg_exclude_products_by_attribute($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (is_shop() || is_product_category() || is_product_tag() || is_search()) {
// Атрибут и значение для исключения
$attribute_taxonomy = 'pa_sezon'; // замените на нужный атрибут
$term_slug = 'zima'; // замените на нужное значение
$tax_query = $query->get('tax_query');
if (!is_array($tax_query)) {
$tax_query = [];
}
$tax_query[] = [
'taxonomy' => $attribute_taxonomy,
'field' => 'slug',
'terms' => [$term_slug],
'operator' => 'NOT IN',
];
$query->set('tax_query', $tax_query);
}
}Этот код добавляет условие, исключающее из выборки товары с указанным значением атрибута.
2. Исключение отдельных вариантов товаров (вариаций) по атрибуту
Исключить вариации сложнее, так как они хранятся как отдельные продукты типа product_variation. Нужно исключать варианты на уровне запроса и при выводе вариаций.
Добавим фильтр, который исключит вариации с нужным атрибутом из каталога и поиска:
add_action('pre_get_posts', 'wpreg_exclude_variations_by_attribute');
function wpreg_exclude_variations_by_attribute($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if ((is_shop() || is_product_category() || is_product_tag() || is_search()) && $query->get('post_type') === 'product_variation') {
global $wpdb;
$attribute_meta_key = 'attribute_pa_cvet'; // замените на ваш атрибут с префиксом attribute_pa_ (для вариаций)
$excluded_value = 'krasnyj';
// Получаем ID вариантов с указанным атрибутом
$variation_ids = $wpdb->get_col($wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s",
$attribute_meta_key,
$excluded_value
));
if (!empty($variation_ids)) {
$query->set('post__not_in', $variation_ids);
}
}
}Этот код исключит из выборки вариации с атрибутом "Цвет" = "Красный".
Проверка результата после внедрения
- Очистите кэш сайта и браузера.
- Перейдите на страницу магазина, категорий и выполните поиск, чтобы убедиться, что товары и варианты с указанными атрибутами не отображаются.
- Проверьте, что остальные товары показываются корректно.
- Для проверки вариаций можно использовать отладчик запросов или вывести ID вариантов в админке.
Частые ошибки и как их исправить
- Неправильный slug атрибута или значения: используйте
get_terms()или админку для проверки точных slug. - Код не срабатывает в кастомных шаблонах: убедитесь, что
pre_get_postsприменяется к основному запросу и не конфликтует с другими фильтрами. - Кэширование мешает обновлению: отключите плагин кэширования или очистите все кэши после внесения изменений.
- Вариации продолжают отображаться: проверьте, что правильно указан meta_key для вариаций с префиксом
attribute_pa_.
Практические советы по безопасности и производительности
- Не используйте тяжелые запросы в
pre_get_posts, чтобы не замедлять сайт. При необходимости кешируйте результаты. - Всегда проверяйте, что фильтры применяются только к фронтенду и основному запросу, чтобы избежать конфликтов в админке.
- Используйте дочернюю тему или собственный плагин для хранения кода, чтобы при обновлении темы изменения не потерялись.
- При использовании WP-Cron и кэширования убедитесь, что изменения не отменяются автоматическими процессами и кешем.
Таблица сравнения вариантов решения
| Метод | Описание | Преимущества | Недостатки |
|---|---|---|---|
Код через pre_get_posts | Исключение товаров и вариаций в запросах WordPress | Гибко, бесплатно, без плагинов | Требует навыков, может конфликтовать с другими фильтрами |
| Плагины фильтрации товаров | Готовые решения с UI для исключения товаров по атрибутам | Простота настроек, расширенный функционал | Платные, могут замедлять сайт |
| Изменение шаблонов темы | Фильтрация на уровне шаблонов PHP | Контроль над выводом | Менее удобно, возможны ошибки при обновлениях |