Как настроить похожие товары WooCommerce?
У меня есть следующие строки кода на сайте, которые отображают похожие товары внизу страницы отдельного товара в WooCommerce...
functions.php:
// отображение сопутствующих и похожих товаров внутри выделенного div с различным количеством колонок и товаров
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products',20);
remove_action( 'woocommerce_after_single_product', 'woocommerce_output_related_products',10);
add_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);
function woocommerce_output_related_products() {
$output = null;
ob_start();
woocommerce_related_products(4,4);
$content = ob_get_clean();
if($content) { $output .= $content; }
echo '<div class="clear"></div>' . $output;
}
Поскольку он отображает 4 товара, которые были отнесены к одной и той же категории, как мне изменить вышеуказанный код, чтобы вместо этого отображались товары с похожими метками?
Например, у меня есть категория товаров под названием 'Автомобили', и внутри этой категории есть несколько меток - 'Holden', 'Ford', 'Toyota', 'Nissan' и т.д.
Я хотел бы, чтобы внизу отображались 4 товара, связанные с меткой того товара, который пользователь просматривает в данный момент.
Во-первых, вы не можете сразу достичь цели, которую описали, с помощью кода, который показали в своем вопросе. Чтобы понять, почему нет прямого подхода с этим кодом, вам нужно разобраться, что делает функция woocommerce_related_products()
, которую вы используете.
Во-вторых, вам необходимо разобраться в сути вопроса, иначе вы не сможете задать точный вопрос, что должно быть вашей главной целью, чтобы получить ответ. Кроме того, следует учитывать, что WordPress Development в первую очередь ориентирован на вопросы, связанные с ядром WordPress — если вам интересно, это обсуждается в Wordpress Development Meta, в частности, в теме Our wooes and future of platform plugins at WPSE. Поэтому, если вы задаете вопросы о плагинах, таких как WooCommerce, вам нужно разбить их на более простые части, максимально приближенные к функциям ядра — см. следующий пункт — так как вы не можете ожидать, что люди будут знать каждую деталь каждого плагина, который вы используете.
В-третьих, давайте углубимся в понимание происходящего. Как вы сказали, вы используете функцию woocommerce_related_products()
. Если посмотреть ее исходный код, можно увидеть, что она использует woocommerce_get_template()
для получения шаблона related.php
. В свою очередь, woocommerce_get_template()
использует woocommerce_locate_template()
для поиска шаблона, а последний делает это с помощью функции ядра WordPress locate_template()
.
Теперь мы видим связь с ядром, что приводит к осознанию того, что упомянутые (и, надеюсь, изученные) функции WooCommerce по сути являются обертками для расширения функциональности ядра. Также становится ясно, что для достижения вашей цели нужен другой подход, поскольку woocommerce_related_products()
— теперь очевидно — не подходит.
Если вы следили за моими объяснениями и внимательно читали, то поняли, что в файле related.php
содержится то, что вы ищете. В частности, речь идет о функции get_related()
, которая включает хук woocommerce_product_related_posts
и использует функции ядра wp_get_post_terms()
и get_posts()
— get_related()
используется для получения набора ID. Кроме того, есть хук woocommerce_related_products_args
, который можно использовать для изменения аргументов запроса связанных товаров внутри related.php
, для этого используется WP_Query
. Запрос использует ID, полученные из вызова get_related()
.
Думаю, у вас теперь есть все необходимое для решения вашей проблемы. На самом деле даже больше — это почти полный обзор того, как кастомизировать связанные товары. Я не упомянул все функции и хуки из исходного кода, но точно все важные. Теперь должно быть понятнее, как функциональность связанных товаров WooCommerce сводится к функциям ядра WordPress.
В-четвертых, перейду к тому, где следует применять ваши изменения и как следовало сформулировать вопрос. Например, так:
WooCommerce предоставляет хук woocommerce_product_related_posts
для кастомизации вызова get_posts()
при определении связанных товаров.
Код:
// Получаем записи
$related_posts = get_posts( apply_filters('woocommerce_product_related_posts', array(
'orderby' => 'rand',
'posts_per_page' => $limit,
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
array(
'taxonomy' => 'product_tag',
'field' => 'id',
'terms' => $tags_array
)
)
) ) );
Как я могу изменить этот код, чтобы достичь своей цели? А именно: показывать связанные товары, которые находятся в той же категории (product_cat
) и имеют те же метки (product_tag
), что и отображаемый товар.
Не давая окончательного ответа (по крайней мере, если вы ожидали готовый код), первое, что вам, вероятно, следует сделать, — изменить параметр relation
в tax_query
с OR
на AND
.
Примечания:
- Я сделал этот ответ более подробным, учитывая обсуждение по ссылкам выше.
- Надеюсь, вы не против, что это не только ответ на ваш вопрос, но и материал с образовательной целью.
- Это не протестировано, так как здесь нет готового кода.
- И последнее: с выходом WooCommerce 2.1.0 ожидаются значительные изменения в коде, учитывайте это, но на данный момент (версия 2.0.19) приведенный код актуален.
Обновление:
Вам не стоит напрямую редактировать классы плагинов (или ядра). Это проблематично, потому что при обновлениях ваши изменения будут перезаписаны, особенно если их легко избежать, как в данном случае. Ниже приведен код, который делает то, что вы хотели, но через functions.php
.
Код:
add_filter( 'woocommerce_product_related_posts',
'wpse_123436_change_wc_related_products_relation_to_and' );
function wpse_123436_change_wc_related_products_relation_to_and() {
$get_related_products_args = array(
'orderby' => 'rand',
'posts_per_page' => $limit,
'post_type' => 'product',
'fields' => 'ids',
'meta_query' => $meta_query,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $cats_array
),
array(
'taxonomy' => 'product_tag',
'field' => 'id',
'terms' => $tags_array
)
)
);
return $get_related_products_args;
}
Для WooCommerce версии 2.1.0 и выше указанный хук не будет работать, так как он больше не существует. Этот ответ актуален до версии 2.0.20. Но @NathanPowell нашел хороший ответ на StackOverflow относительно набора хуков, доступных для кастомизации связанных товаров начиная с версии 2.1.0.

Большое спасибо @ialocin за быстрый и подробный ответ. В качестве временной меры я просто заменил OR
на AND
в файле wp-content/plugins/woocommerce/classes/abstract/abstract-wc-product.php
и скоро перенесу это изменение в файл functions.php
. Ещё раз спасибо.

@user1752759 Смотрите моё изменение для реализации этого через functions.php

Идеальный ответ! Его нужно включить в любое руководство о том, как понимать плагины и адаптировать их под свои нужды. Не уверен, что такие книги существуют.. Но всё равно :)

@ThdK Спасибо, не знаю, насколько это хорошо, но после первого прочтения с момента написания я все еще доволен ответом, кроме того, я, конечно, ценю комплимент, всегда приятно это слышать :) Вы пробовали это с WC 2.1.x?

Привет, @ialocin. В отредактированной версии внизу не хватает нескольких закрывающих скобок, и, к сожалению, она больше не работает как решение в версии 2.1.8. Если это не слишком большая просьба, не могли бы вы обновить это для меня?

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

@Jk_ Всегда пожалуйста! У вас это уже работает? И если да, то на какой версии WooCommerce?

Я не реализовал фильтр, как вы упомянули. Я модифицировал related.php в своей теме, чтобы адаптировать запрос. В моем случае я хотел найти связанные товары на основе 'meta_query'. Но ваш ответ был настолько вдохновляющим, что я не мог не оставить комментарий.

Давайте не будем обманывать себя, ребята. Принятый ответ лишь помог пользователю достичь его цели.
Самая первая проблема заключается вот в чем:
<?php
// отображение апсейлов и связанных товаров внутри отдельного div с другим количеством колонок и товаров
remove_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products',20);
remove_action( 'woocommerce_after_single_product', 'woocommerce_output_related_products',10);
add_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);
Действие удаляется, а затем размещается в ТОЧНО той же позиции, откуда было удалено. Цель совершенно непонятна.
Я наткнулся на это, когда искал информацию о связанных товарах, потому что не понимал, что именно ТЕГИ и КАТЕГОРИИ управляют функцией woocommerce_output_related_products
в этом плагине.
Лучший ответ на ЭТОТ вопрос — следующая ссылка, и он напрямую связан с фильтром woocommerce_output_related_products_args()
: https://stackoverflow.com/questions/23554993/output-posts-relating-to-the-tags

Это действительно довольно забавно. Почему, спросите вы? Потому что, если вы внимательно прочитали мой ответ, то увидели бы, что в нем используется только один фильтр. Если быть точным, единственный фильтр, доступный в то время, но вы бы знали это, если бы действительно прочитали то, что я написал, и потратили бы время на изучение исходных файлов разных версий. Просто к слову. Кроме того, в ответе, на который вы ссылаетесь, очень хорошо объяснены новые хуки, доступные начиная с версии 2.1.

Извините за это, была поздняя ночь. Я надеялся немного объяснить очевидную ошибку в коде автора вопроса.

Не беспокойтесь, но я чувствовал, что должен был что-то сказать.
