Как настроить похожие товары WooCommerce?

16 нояб. 2013 г., 04:52:17
Просмотры: 97.4K
Голосов: 16

У меня есть следующие строки кода на сайте, которые отображают похожие товары внизу страницы отдельного товара в 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 товара, связанные с меткой того товара, который пользователь просматривает в данный момент.

0
Все ответы на вопрос 2
9
33

Во-первых, вы не можете сразу достичь цели, которую описали, с помощью кода, который показали в своем вопросе. Чтобы понять, почему нет прямого подхода с этим кодом, вам нужно разобраться, что делает функция 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.

16 нояб. 2013 г. 17:07:09
Комментарии

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

user1752759 user1752759
17 нояб. 2013 г. 06:28:33

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

Nicolai Grossherr Nicolai Grossherr
18 нояб. 2013 г. 13:01:03

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

ThdK ThdK
6 апр. 2014 г. 22:23:04

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

Nicolai Grossherr Nicolai Grossherr
7 апр. 2014 г. 12:05:43

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

user1752759 user1752759
6 мая 2014 г. 07:21:00

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

Nicolai Grossherr Nicolai Grossherr
6 мая 2014 г. 13:42:05

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

Nicolai Grossherr Nicolai Grossherr
12 сент. 2014 г. 00:09:33

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

Nypam Nypam
12 сент. 2014 г. 00:50:51

Спасибо! Жаль, мне просто было интересно из-за предыдущего комментария. @Jk_

Nicolai Grossherr Nicolai Grossherr
12 сент. 2014 г. 01:29:44
Показать остальные 4 комментариев
4

Давайте не будем обманывать себя, ребята. Принятый ответ лишь помог пользователю достичь его цели.

Самая первая проблема заключается вот в чем:

<?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

30 сент. 2014 г. 10:46:05
Комментарии

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

Nicolai Grossherr Nicolai Grossherr
6 окт. 2014 г. 22:17:44

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

Nathan Powell Nathan Powell
16 окт. 2014 г. 18:51:52

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

Nicolai Grossherr Nicolai Grossherr
18 окт. 2014 г. 09:40:24

Твоя ссылка-пример сработала у меня, Натан, спасибо, я уже 2 часа пытался сделать это сам. Теперь я знаю, как правильно применять фильтры :)

marcovega marcovega
8 июл. 2015 г. 12:41:11