Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have the following lines of code in my website that will display the related products at the bottom of my single product page in WooCommerce...

functions.php:

// display upsells and related products within dedicated div with different column and number of products
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;
}

As it displays 4 products that have been categorized under the same name, how would I modify the above, to display the related tags instead?

For example, I have a product category called 'Automotive' and within this category, are a few tags - 'Holden', 'Ford', 'Toyota', 'Nissan' etc.

I would like it to display 4 products at the bottom, related to the tag of the product the user is currently viewing.

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

Firstly, you can't immediately achieve the goal you described with the code you show in your question. To understand why there isn't a direct approach with that code you have to take a look at what you're using - woocommerce_related_products() - to do what you have done so far.

Secondly, you have to understand, because otherwise you are not able to ask a on point question, which should absolutely be your goal, to assure you're getting an answer. Besides that you have to keep in mind that Wordpress Development has it's primary scope set on wordpress core related questions - if you're interested, this is under discussion on Wordpress Development Meta, one specific topic being Our wooes and future of platform plugins at WPSE. So, if you're asking questions about plugins, like woocommerce, you should break it down to make it as related to core functions as possible - see the next point - as you can't expect people to know every detail of every plugin you're using.

Thirdly, now lets get into a deeper insight what's happening. As you said, you're using woocommerce_related_products() now. If you take a look at the source you see that this function uses woocommerce_get_template() to get the related.php template. woocommerce_get_template() again uses woocommerce_locate_template() to locate the template, the latter is doing so by making use of the wordpress core function locate_template().
Now there is a connection back to core, leading to the realization that the above mentioned - and hopefully inspected - woocommerce functions are essentially wrappers to extend core functionality. Another thing that became clear by analyzing the functionality dependencies is, what I said before, you need a different approach to achieve your goal, because woocommerce_related_products() - now undeniable obvious - isn't the correct one.
If you followed me with my explanations and have read thoroughly so far, you realized that the related.php contains what you are looking for. I'm especially talking about the get_related() function, which includes the woocommerce_product_related_posts hook and makes use of the core functions wp_get_post_terms() and get_posts() - get_related() is used to get a set of ids. Additionally there is the woocommerce_related_products_args hook, which can be used to alter the arguments of the related products query inside related.php, WP_Query is used for this. The query uses the resulting ids from the get_related() call.
I think you got everything on hand now to solve your problem. Actually way more than that, this gives a almost complete overview on how to customize the related products. I did not mention every functionality - function and/or hook - out of source code inspected, but definitely all the important ones. It now should be clearer how the related products functionality of woocommerce can be traced back to wordpress core functions.

Fourthly, I come to, where you should apply your customizations and what you should have asked for. For example like this:

Woocommerce has the woocommerce_product_related_posts hook to customize the get_posts() call to determine related products.

Code:

        // Get the 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
                        )
                )
        ) ) );

How can I customize this to achieve my goal? Which is to show related products that are in the same product category - product_cat - and have the same tag(s) - product_tag - as the single product shown.

Without giving you a concluding - at least not if you had expectation to get complete and ready made code - answer, the first thing you probably should do is change the tax_query parameter relation from OR to AND.





Notes:

  • I made this a longer descriptive answer with the above linked ongoing discussion in mind
  • I hope you don't mind, that it's not only an answer to your question, but additionally pursues to fulfill a general educational purpose
  • this is untested, because there is no actual ready made code
  • last but not least, it's foreseeable that with the release of woocoomerce 2.1 some significant code changes will be implemented, bare that in mind, but for now as of 2.0.19 the above code is valid



Edit:

You really shouldn't edit (plugin) core classes directly. It's problematic, because you have to maintain your changes on updates again, as the core files get updated and overwritten if you perform one. Especially if it's easily avoidable like in this case, below code does what you intended to do anyways, which is, implementing this change via your functions.php.

Code:

    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;
    }

Note: untested

share|improve this answer
    
Thank you very much @ialocin for the quick and detailed response. As a temporary measure, I simply changed the OR to AND in my wp-content/plugins/woocommerce/classes/abstract/abstract-wc-product.php file and will soon change this to be done from within the functions.php file. Thank you again. –  user1752759 Nov 17 '13 at 4:28
    
@user1752759 See my edit to do this via functions.php –  ialocin Nov 18 '13 at 11:01
    
Perfect answer! It should be used in any guidebook on how to understand plugins and how to extend them to your needs. Not sure if these books exists though.. But still :) –  ThdK Apr 6 at 19:23
    
@ThdK Thanks, I don't know if it is that good, but after reading it the first time since writing it I'm still happy with the answer, besides that I surely appreciate the compliment, it's always nice to hear :) Have you tried this with WC 2.1.x? –  ialocin Apr 7 at 9:05
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.