wpcore.ru wordpress wpcore.ru

Как отключить отображение товаров в наличии для некоторых категорий в WooCommerce

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

Когда это действительно нужно

Чаще всего задача появляется в магазинах с разной логикой продаж: часть ассортимента продаётся со склада, часть — под заказ, а часть вообще не должна отвлекать покупателя наличием. Например, в категории «Распродажа» можно оставить только остатки, а в категории «Предзаказ» скрыть всё, что уже доступно на складе. Важно не путать эту задачу с глобальным скрытием отсутствующих товаров: здесь мы меняем поведение только для выбранных категорий.

Диагностика проблемы перед изменениями

Перед правкой кода проверьте, где именно сейчас формируется список товаров. В WooCommerce на вывод могут влиять тема, фильтры каталога, плагины для сортировки и кэш. Если товары в наличии уже скрываются где-то ещё, новый фильтр даст неожиданный результат.

  • Откройте проблемную категорию в обычном каталоге и в режиме инкогнито.
  • Проверьте, не включена ли опция скрытия отсутствующих товаров в настройках WooCommerce.
  • Посмотрите, не меняет ли тема запрос через pre_get_posts или собственные хуки каталога.
  • Если используется кэш страницы, очистите его до теста и после правки.

Если в админке товары помечены как «В наличии», но на витрине они не показываются, причина обычно не в карточке товара, а в логике основного запроса или в фильтре видимости.

Подходы: плагин, код или настройка темы

Для такой задачи есть три реалистичных варианта. Настройка WooCommerce подходит только для общего поведения магазина. Плагин удобен, если нужен интерфейс для контент-менеджера. Код — лучший вариант, если правило должно зависеть от конкретных категорий и не расползаться по сайту.

ПодходКогда использоватьМинус
Настройки WooCommerceНужно скрыть отсутствующие товары вездеНе решает задачу выборочно по категориям
ПлагинНужен интерфейс без правки кодаДополнительная зависимость и риск конфликта
Код в дочерней теме или мини-плагинеНужна точная логика по категориямТребуется аккуратное тестирование

Пошаговое решение через фильтр WooCommerce

Ниже пример, который скрывает товары в наличии только в выбранных категориях. Логика строится на фильтре woocommerce_product_is_visible. Он срабатывает при формировании каталога и позволяет убрать товар из выдачи, не меняя саму карточку товара.

<?php
add_filter( 'woocommerce_product_is_visible', 'wpcore_hide_instock_products_in_selected_categories', 10, 2 );

function wpcore_hide_instock_products_in_selected_categories( $visible, $product_id ) {
    if ( ! $visible ) {
        return $visible;
    }

    if ( is_admin() ) {
        return $visible;
    }

    $target_categories = array( 'pre-order', 'clearance' );

    if ( ! has_term( $target_categories, 'product_cat', $product_id ) ) {
        return $visible;
    }

    $product = wc_get_product( $product_id );

    if ( ! $product ) {
        return $visible;
    }

    if ( $product->is_in_stock() ) {
        return false;
    }

    return $visible;
}

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

Если нужно скрывать именно товары без остатка

Иногда задача формулируется наоборот: в отдельных категориях показывать только товары в наличии, а отсутствующие убирать. Тогда меняется только проверка статуса склада.

<?php
add_filter( 'woocommerce_product_is_visible', 'wpcore_hide_outofstock_products_in_selected_categories', 10, 2 );

function wpcore_hide_outofstock_products_in_selected_categories( $visible, $product_id ) {
    if ( ! $visible || is_admin() ) {
        return $visible;
    }

    $target_categories = array( 'sale', 'featured' );

    if ( ! has_term( $target_categories, 'product_cat', $product_id ) ) {
        return $visible;
    }

    $product = wc_get_product( $product_id );

    if ( ! $product ) {
        return $visible;
    }

    if ( ! $product->is_in_stock() ) {
        return false;
    }

    return $visible;
}

Как проверить, что решение сработало

Проверка должна быть не только визуальной. Иначе можно пропустить ситуацию, когда товар исчез из каталога, но остался в поиске или в блоке «Похожие товары».

  1. Откройте категорию, на которую распространяется правило.
  2. Сравните товары в наличии и без остатка: должны остаться только те, которые соответствуют условию.
  3. Проверьте поиск по сайту и страницу товара напрямую по URL.
  4. Если используются фильтры по атрибутам, убедитесь, что скрытые товары не возвращаются в выдаче фильтра.
  5. Очистите кэш страницы и объектный кэш, если он есть.

Для быстрой диагностики можно временно вывести статус товара в шаблоне категории или в лог. Если товар виден в админке, но не проходит фильтр, обычно проблема в неверном slug категории или в том, что товар принадлежит не только целевой категории.

Частые ошибки и как их исправить

Используют название категории вместо slug

Функция has_term() надёжнее работает со slug. Если передать русское название категории, совпадение может не сработать, особенно после переименования термина. Проверьте slug в разделе «Товары → Категории».

Ставят код в тему без учёта обновлений

Если код добавлен прямо в functions.php родительской темы, он может потеряться при обновлении. Для таких правок лучше использовать дочернюю тему или небольшой must-use плагин.

Не учитывают кэш и AJAX-фильтры

Некоторые темы и плагины строят каталог через AJAX. В этом случае товар может исчезнуть на основной странице, но остаться в подгружаемом блоке. После внедрения проверьте и обычный архив, и AJAX-фильтрацию, и результаты поиска.

Путают видимость товара и остаток

Статус in stock не равен «показывать в каталоге». Товар может быть в наличии, но скрыт настройками видимости, каталогом по ролям или отдельным плагином. Если правило не работает, сначала проверьте саму карточку товара в WooCommerce.

Если нужен более управляемый вариант

Когда правило должно редактироваться менеджером без разработчика, удобнее вынести список категорий в настройку или использовать плагин с интерфейсом. Но если задача простая и завязана на конкретные категории, код остаётся самым предсказуемым вариантом. Важно только не разбрасывать его по нескольким местам: один фильтр, одна точка правды.

Безопасность и производительность

Фильтр woocommerce_product_is_visible вызывается часто, поэтому не стоит добавлять в него тяжёлые запросы к базе или внешние HTTP-вызовы. Используйте только то, что уже есть в WooCommerce: wc_get_product(), has_term() и простую проверку статуса. Если категорий много и логика сложнее, лучше заранее собрать список целевых term ID и не вычислять его на каждом запросе.

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

Когда лучше не скрывать товары кодом

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

×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее