Диагностика проблемы: почему ненужные товары показываются в связанных товарах WooCommerce
Часто при использовании стандартного функционала WooCommerce для показа связанных товаров можно столкнуться с ситуацией, когда в блоке связанных товаров выводятся товары, которые не должны там отображаться — например, распроданные (статус "нет в наличии"), товары определённых категорий или с заданными метаданными.
Это ухудшает UX и может снизить конверсию, поэтому важно научиться исключать такие товары автоматически, без ручного вмешательства.
Как WooCommerce выбирает связанные товары
По умолчанию WooCommerce выводит связанные товары на основе категорий и тегов текущего товара, а также случайным образом подбирает определённое количество товаров. Однако, фильтрация по статусу товара или дополнительным метаданным не встроена и требует кастомизации.
Пошаговое решение: фильтрация связанных товаров через хук woocommerce_related_products
1. Отключение стандартного вывода связанных товаров (опционально)
Если нужно полностью контролировать блок связанных товаров, можно отключить стандартный вывод в теме:
remove_action('woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);2. Использование фильтра woocommerce_related_products для исключения товаров
Этот фильтр позволяет изменить массив ID товаров, которые WooCommerce использует для показа связанных.
Добавим в functions.php или в кастомный плагин следующий код:
add_filter('woocommerce_related_products', 'custom_exclude_products_from_related', 10, 3);
function custom_exclude_products_from_related($related_posts, $product_id, $args) {
$filtered = array();
foreach ($related_posts as $related_id) {
$product = wc_get_product($related_id);
if (!$product) continue;
// Исключаем товары, которых нет в наличии
if (!$product->is_in_stock()) continue;
// Исключаем товары с мета-ключом _exclude_from_related, установленным в 'yes'
$exclude_flag = get_post_meta($related_id, '_exclude_from_related', true);
if ($exclude_flag === 'yes') continue;
$filtered[] = $related_id;
}
return $filtered;
}3. Как назначить мета-данные для исключения товаров
Чтобы пометить товар для исключения из связанных, можно вручную добавить мета-ключ _exclude_from_related со значением yes через плагин Advanced Custom Fields (ACF) или через админку (плагины типа Adminer, WP phpMyAdmin).
4. Исключение товаров по категориям
Если нужно исключить целые категории товаров из связанных, добавьте проверку категорий:
add_filter('woocommerce_related_products', 'exclude_category_from_related', 20, 3);
function exclude_category_from_related($related_posts, $product_id, $args) {
$excluded_cats = array('excluded-category-slug'); // Замените на слаги категорий
$filtered = array();
foreach ($related_posts as $related_id) {
$terms = wp_get_post_terms($related_id, 'product_cat', array('fields' => 'slugs'));
if (array_intersect($excluded_cats, $terms)) continue;
$filtered[] = $related_id;
}
return $filtered;
}Проверка результата после внедрения
- Откройте страницу товара на фронтенде.
- Посмотрите блок связанных товаров — товары с пометкой
_exclude_from_related = yesи распроданные товары должны отсутствовать. - Для проверки можно временно вывести ID связанных товаров в шаблоне single-product/related.php или включить WP_DEBUG и использовать
error_log(print_r($related_posts, true));.
Частые ошибки и как их исправить
- Код не работает или товары не исключаются: проверьте правильность мета-ключа и его значения, убедитесь, что фильтр подключен и не конфликтует с другими плагинами.
- Кэширование мешает увидеть изменения: очистите кэш сайта и браузера.
- Вывод связанных товаров исчез полностью: проверьте логи на наличие ошибок в PHP, убедитесь, что после фильтра возвращается массив с товарами.
- Неправильное использование хуков: используйте
woocommerce_related_productsдля изменения массива ID, а неwoocommerce_output_related_products_argsдля фильтрации постов.
Практические советы по производительности и безопасности
- Не делайте избыточных запросов внутри цикла, кешируйте результаты, если работаете с большим количеством товаров.
- Избегайте использования
get_post_metaв цикле без необходимости — можно заранее получить метаданные черезupdate_meta_cache. - Проверяйте, что фильтрация не влияет на SEO — не исключайте слишком много товаров, чтобы избежать пустых блоков.
- Следите за безопасностью, не выводите в лог и на экран данные, содержащие приватную информацию.
Сравнение способов исключения товаров из связанных
| Метод | Плюсы | Минусы | Пример использования |
|---|---|---|---|
Фильтр woocommerce_related_products с PHP |
Гибкая кастомизация, не требует плагинов | Требует навыков программирования | Код из статьи |
| Плагины фильтрации WooCommerce Related Products | Простота использования, UI для настройки | Могут влиять на производительность, меньше контроля | WooCommerce Related Products Manager (платный) |
| Изменение через шаблоны темы | Полный контроль вывода | Требует поддержки при обновлениях темы | Копирование и изменение related.php |