Как скрыть вариативные товары из каталога WooCommerce и оставить их доступными по прямой ссылке

Сценарий знакомый: в каталоге магазина показываются и родительский товар, и его вариации, а иногда ещё и отдельные вариативные позиции из импорта. В результате покупатель видит дубли, фильтры начинают вести себя странно, а менеджеру приходится вручную объяснять, почему один и тот же товар встречается несколько раз. Если задача именно в том, чтобы убрать вариативные товары из листинга, но не ломать карточку товара и прямые ссылки, это лучше решать на уровне вывода, а не через удаление товаров из каталога целиком.

Когда это действительно проблема

Чаще всего речь не о «косметике», а о конкретных сбоях в витрине:

  • в категории показывается родительский товар и отдельные вариации;
  • в поиске дублируются позиции с одинаковым названием;
  • фильтры по цене и наличию считают вариации как отдельные товары;
  • в карточке товара всё работает, но каталог перегружен лишними строками;
  • нужно оставить вариативный товар доступным по прямой ссылке, для рекламы или SEO-страниц.

Что обычно ломают при попытке исправить это быстро

Самая частая ошибка — менять тип товара или удалять вариации, чтобы «почистить» каталог. Это почти всегда приводит к побочным эффектам: исчезают цены, ломаются остатки, перестают работать вариации в корзине. Второй плохой вариант — прятать товар через CSS. Он остаётся в DOM, индексируется и продолжает участвовать в логике плагинов фильтрации.

Диагностика: где именно появляются дубли

Перед правкой кода проверьте, что именно выводится в каталоге. В WooCommerce вариативный товар в норме должен отображаться как один родительский товар, а вариации — только внутри карточки. Если вы видите отдельные вариации в архиве, это обычно означает одно из трёх:

  1. тема переопределила шаблон каталога и выводит дочерние товары вручную;
  2. сторонний плагин каталога или фильтрации подменяет запрос;
  3. в импорте вариации были созданы как отдельные простые товары.

Быстрая проверка без кода: откройте страницу категории, посмотрите 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.

Если после этого каталог стал чище, а карточки товаров не потеряли функциональность, значит задача решена правильно: вы убрали лишний шум из витрины, но не сломали структуру магазина.

Наш каталог плагинов WordPress