Диагностика задачи: зачем исключать товар из каталога и поиска
В реальных проектах на WooCommerce часто возникает необходимость временно или постоянно скрыть товар из каталога и результатов поиска, но при этом сохранить его в базе данных и доступным по прямой ссылке. Это нужно, например, для товаров, которые временно отсутствуют, или для определённых категорий товаров, которые не должны быть видны большинству пользователей.
Почему не стоит просто удалять товар
- Потеря данных о товаре, настройках и мета.
- Нарушение связей с заказами и отчетами.
- Потеря SEO-позиций, если товар был проиндексирован.
Пошаговое решение: как скрыть товар из каталога и поиска через код
Самый надежный и минимально инвазивный способ — добавить фильтр на запрос товаров WooCommerce, чтобы исключить нужные товары по ID или по другому признаку (например, по мета-полю или категории). Ниже пример кода, который исключает товары с определенными ID из каталога и поиска:
add_action('pre_get_posts', 'exclude_products_from_catalog_and_search');
function exclude_products_from_catalog_and_search($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (is_shop() || is_product_category() || is_product_tag() || is_search()) {
// IDs товаров для исключения
$excluded_ids = array(123, 456, 789);
$query->set('post__not_in', $excluded_ids);
}
}В этом примере товары с ID 123, 456 и 789 не будут выводиться на страницах магазина, категорий, тегов и в результатах поиска.
Как сделать исключение динамическим через мета-поле
Если нужно массово управлять скрытием товаров без изменения кода, можно добавить кастомное мета-поле, например hide_from_catalog со значением 1. Тогда код изменится так:
add_action('pre_get_posts', 'exclude_products_by_meta_from_catalog_and_search');
function exclude_products_by_meta_from_catalog_and_search($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (is_shop() || is_product_category() || is_product_tag() || is_search()) {
$meta_query = array(
array(
'key' => 'hide_from_catalog',
'value' => '1',
'compare' => '!='
)
);
$query->set('meta_query', $meta_query);
}
}Теперь товары с мета-полем hide_from_catalog=1 будут исключены из вывода.
Как проверить, что решение работает
- Очистите кеш сайта и браузера.
- Перейдите на страницу магазина и проверьте, что указанные товары не отображаются.
- Сделайте поиск по названию скрытого товара — он не должен появляться в результатах.
- Откройте прямую ссылку на скрытый товар — страница должна открываться нормально.
Частые ошибки и как их исправить
- Код не срабатывает на страницах архива: проверьте, что
is_main_query()и!is_admin()используются правильно, чтобы не влиять на админку и дополнительные запросы. - Товар всё равно показывается: возможно, другие плагины или тема модифицируют запросы — проверьте порядок подключения фильтров.
- Проблемы с пагинацией: при использовании
post__not_inубедитесь, что пагинация учитывает исключённые товары, иначе возможны пустые страницы. - Неправильное использование
meta_query: для исключения по мета-полю используйте отрицательное сравнение'compare' => '!='и убедитесь, что другие мета-запросы не конфликтуют.
Практические советы по безопасности и производительности
- Добавляйте код в дочернюю тему или через собственный плагин, чтобы избежать потери при обновлениях.
- Для больших магазинов с тысячами товаров лучше использовать мета-поле для исключения, а не массивы ID, чтобы снизить нагрузку на запросы.
- Кешируйте страницы магазина и результаты поиска через серверный кеш, чтобы минимизировать нагрузку.
- Проверяйте совместимость с плагинами кеширования и оптимизации, например Clearfy Pro (ссылка), чтобы избежать конфликтов.
Сравнение подходов: код vs плагины
| Подход | Плюсы | Минусы |
|---|---|---|
| Код (фильтр pre_get_posts) | Легко кастомизировать, минимальная нагрузка, полный контроль | Требует навыков PHP, риск ошибок при неправильном коде |
| Плагины скрытия товаров (например, "WooCommerce Catalog Visibility Options") | Удобный интерфейс, дополнительные функции (групповое скрытие, роли пользователя) | Может влиять на производительность, не всегда бесплатно, возможны конфликты |