Проблема: лишние товары в блоке связанных товаров WooCommerce
WooCommerce автоматически выводит связанные товары на основе категорий и тегов. Но иногда нужно исключить из списка, например, товары по определённым метаданным — например, товары со статусом "скрыт" или с определённым флагом в мета-поле. Стандартных настроек для этого нет, поэтому приходится вмешиваться программно.
Диагностика проблемы
Чтобы понять, почему в блоке связанных товаров появляются нежелательные позиции, проверьте:
- Какие метаданные есть у товаров, которые нужно исключить.
- Какие критерии WooCommerce использует для вывода связанных товаров (обычно категории и теги).
- Отсутствует ли фильтр по метаданным в запросе, который выводит связанные товары.
Подключитесь к базе данных или используйте плагин как Query Monitor для изучения WP_Query, который формирует связанные товары.
Пошаговое решение: исключение товаров по метаданным через фильтр запроса
Для исключения товаров с определённым метаполем воспользуемся хуком woocommerce_product_related_posts_relate_by_category или, более универсально, перехватим WP_Query через фильтр woocommerce_related_products_args. Ниже пример исключения товаров с мета-ключом _exclude_from_related равным yes:
add_filter('woocommerce_related_products_args', 'exclude_products_by_meta_from_related', 10, 1);
function exclude_products_by_meta_from_related($args) {
// Получаем ID товаров с мета _exclude_from_related = 'yes'
$excluded_ids = get_posts(array(
'fields' => 'ids',
'post_type' => 'product',
'meta_key' => '_exclude_from_related',
'meta_value' => 'yes',
'posts_per_page' => -1
));
if (!empty($excluded_ids)) {
if (isset($args['post__not_in'])) {
$args['post__not_in'] = array_merge($args['post__not_in'], $excluded_ids);
} else {
$args['post__not_in'] = $excluded_ids;
}
}
return $args;
}Этот код добавляет к стандартному массиву post__not_in ID товаров, которые нужно исключить из связанных.
Проверка результата
- Откройте страницу товара и проверьте блок «Связанные товары».
- Убедитесь, что товары с
_exclude_from_related = yesне отображаются. - Для проверки можно временно добавить
var_dump($args)внутри функции, чтобы увидеть параметры запроса.
Частые ошибки и их причины
- Не исключаются товары: возможно, метаданные неправильно заданы, проверьте через
get_post_meta()или БД. - Все товары исчезают: если в
post__not_inпопадают ID текущего товара или слишком много товаров, список становится пустым. - Кэширование: если на сайте используется кэш, изменения могут не сразу проявиться, очистите кэш.
- Конфликты с другими плагинами: например, с YARPP или плагинами, которые тоже модифицируют связанные товары.
Практические советы по улучшению производительности и безопасности
- Используйте
get_posts()сfields => 'ids'для минимизации нагрузки. - Кэшируйте результат
get_posts(), если список исключаемых товаров большой, например через Transients API. - Не выводите дебаг-код на продакшене.
- Всегда проверяйте, что добавляемые ID не включают текущий товар.
Сравнение подходов: плагин против кода
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Плагин для исключения товаров | Простота настройки, не требует кода | Может нагружать сайт, не всегда гибко | Использовать, если нет специфичных требований |
| Кастомный код (как в статье) | Точная настройка, меньше нагрузки | Требует знаний PHP, нужно тестирование | Лучше для разработчиков и кастомных задач |