Сценарий знакомый: в каталоге магазина показываются и родительский товар, и его вариации, а иногда ещё и отдельные вариативные позиции из импорта. В результате покупатель видит дубли, фильтры начинают вести себя странно, а менеджеру приходится вручную объяснять, почему один и тот же товар встречается несколько раз. Если задача именно в том, чтобы убрать вариативные товары из листинга, но не ломать карточку товара и прямые ссылки, это лучше решать на уровне вывода, а не через удаление товаров из каталога целиком.
Когда это действительно проблема
Чаще всего речь не о «косметике», а о конкретных сбоях в витрине:
- в категории показывается родительский товар и отдельные вариации;
- в поиске дублируются позиции с одинаковым названием;
- фильтры по цене и наличию считают вариации как отдельные товары;
- в карточке товара всё работает, но каталог перегружен лишними строками;
- нужно оставить вариативный товар доступным по прямой ссылке, для рекламы или SEO-страниц.
Что обычно ломают при попытке исправить это быстро
Самая частая ошибка — менять тип товара или удалять вариации, чтобы «почистить» каталог. Это почти всегда приводит к побочным эффектам: исчезают цены, ломаются остатки, перестают работать вариации в корзине. Второй плохой вариант — прятать товар через CSS. Он остаётся в DOM, индексируется и продолжает участвовать в логике плагинов фильтрации.
Диагностика: где именно появляются дубли
Перед правкой кода проверьте, что именно выводится в каталоге. В WooCommerce вариативный товар в норме должен отображаться как один родительский товар, а вариации — только внутри карточки. Если вы видите отдельные вариации в архиве, это обычно означает одно из трёх:
- тема переопределила шаблон каталога и выводит дочерние товары вручную;
- сторонний плагин каталога или фильтрации подменяет запрос;
- в импорте вариации были созданы как отдельные простые товары.
Быстрая проверка без кода: откройте страницу категории, посмотрите HTML и убедитесь, что карточка вариации имеет тип товара, отличный от product_variation. Если это именно вариация, её не должно быть в обычном каталоге по умолчанию. Если она всё же есть, значит источник проблемы — тема или плагин.
Рабочее решение через фильтр WooCommerce
Если нужно скрыть вариации из архива товаров, но не трогать сам товар и его URL, удобнее всего отфильтровать список товаров перед выводом. Для этого можно использовать хук woocommerce_product_query и исключить вариации из основного запроса каталога.
add_action( 'woocommerce_product_query', function( $q ) {
if ( is_admin() ) {
return;
}
if ( ! ( is_shop() || is_product_taxonomy() || is_product_category() || is_product_tag() ) ) {
return;
}
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => array( 'variation' ),
'operator' => 'NOT IN',
);
$q->set( 'tax_query', $tax_query );
} );
Этот вариант полезен, если вариации по какой-то причине попадают в архив через запрос. Но на практике чаще нужно не столько менять запрос, сколько убрать конкретные вариации из карточек каталога, где тема выводит их вручную. Тогда логичнее использовать фильтр woocommerce_product_is_visible.
add_filter( 'woocommerce_product_is_visible', function( $visible, $product_id ) {
$product = wc_get_product( $product_id );
if ( ! $product ) {
return $visible;
}
if ( $product->is_type( 'variation' ) ) {
return false;
}
return $visible;
}, 10, 2 );
Этот способ не удаляет товар из базы и не мешает открывать его по прямой ссылке, если ссылка уже есть. Но важно понимать ограничение: если тема или плагин строит свой собственный список товаров и не использует стандартную логику видимости WooCommerce, фильтр может не сработать.
Если вариации показываются из-за темы или плагина
Когда стандартные фильтры не помогают, нужно искать место, где тема подменяет шаблон. Обычно это происходит в файлах архива товаров или в кастомных блоках каталога. В таком случае лучше не править ядро темы, а создать дочернюю тему или небольшой mu-plugin и отключить лишний вывод на уровне шаблона.
Сравнение подходов
| Подход | Когда подходит | Минус |
|---|---|---|
| Фильтр запроса WooCommerce | Вариации попадают в архив через основной запрос | Не помогает при кастомном выводе темы |
| Фильтр видимости товара | Нужно скрыть вариации в стандартной витрине | Не влияет на нестандартные шаблоны |
| Правка шаблона темы | Тема сама выводит лишние карточки | Нужно аккуратно сопровождать обновления |
Как проверить, что решение сработало
После внедрения не ограничивайтесь визуальной проверкой главной категории. Пройдитесь по нескольким сценариям:
- откройте страницу магазина и категорию с вариативными товарами;
- проверьте поиск по названию товара;
- перейдите на карточку товара по прямой ссылке;
- проверьте фильтры по цене и наличию, если они используются;
- посмотрите исходный HTML и убедитесь, что вариации не выводятся как отдельные карточки.
Если у вас включён кэш страницы, очистите его после правки. Иначе можно решить, что код не работает, хотя на самом деле вы смотрите старую версию шаблона.
Частые ошибки и как их исправить
Фильтр добавили, но вариации всё равно видны
Значит, вывод идёт не через стандартный запрос WooCommerce. Проверьте шаблоны темы и плагины, которые меняют каталог. Особенно часто это встречается в конструкторах страниц и плагинах для AJAX-фильтрации.
Скрыли вариации, а карточка товара перестала открываться
Так бывает, если вместо вариаций вы отфильтровали родительский товар или неправильно определили тип товара. В коде нужно проверять именно $product->is_type( 'variation' ), а не полагаться на название или категорию.
После правки сломались фильтры и сортировка
Причина обычно в том, что фильтр запроса добавили слишком агрессивно и он затронул не только каталог, но и AJAX-запросы плагина. В таком случае ограничьте условие только основными архивами и исключите админку, как в примере выше.
Вариации скрылись из каталога, но остались в XML-карте
Это уже вопрос SEO-настроек и генератора карты сайта. Если вариации не должны индексироваться, проверьте, не попадают ли они в sitemap через SEO-плагин. Скрытие из каталога само по себе не гарантирует исключение из индекса.
Практические советы по безопасности и производительности
Не вносите такие правки в файлы родительской темы. Для точечной логики лучше использовать мини-плагин или mu-plugin: так код не потеряется после обновления. Если у вас несколько магазинов на одном шаблоне, вынесите условие в отдельную функцию и включайте его только там, где реально есть проблема.
Если каталог большой, не добавляйте тяжёлые запросы к базе на каждый рендер карточки. Вариант с фильтром видимости обычно дешевле, чем попытка пересобрать список товаров вручную. А если используется кэш страниц, после изменения логики обязательно проверьте, не отдаёт ли сервер старую версию архива.
Для магазинов, где нужно не только скрыть вариации, но и убрать дубли в других местах, иногда удобнее подключить специализированную чистку SEO-дублей и служебных страниц. В экосистеме WPShop для этого есть Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но даже с плагином полезно понимать, что именно вы скрываете и где это влияет на витрину.
Мини-чек-лист перед публикацией
- Проверить, что скрываются только вариации, а не родительские товары.
- Открыть каталог в обычном режиме и в режиме инкогнито.
- Проверить поиск, фильтры и сортировку.
- Очистить кэш страницы и объектный кэш, если он есть.
- Убедиться, что прямые ссылки на товар продолжают открываться.
- Проверить, не попадают ли скрытые вариации в sitemap.
Если после этого каталог стал чище, а карточки товаров не потеряли функциональность, значит задача решена правильно: вы убрали лишний шум из витрины, но не сломали структуру магазина.