Question

I am using WordPress 3.9 and WooCommerce 2.1.8, and wanting to know how I can show a single row of four related posts that the user is currently viewing, which is relative to the tag or tags of the post, rather than the category it is in.

Ideally, I'd like to display four products relating to the tags of the item which is currently being viewed at the bottom of my single product pages, specifically, each one of the relating post's featured images or thumbnails, and the prices. If possible, a solution also scripted from the functions.php file.

The code below is what I have so far, which is displaying the related categories of the post, instead of the tags it is based on:

    add_action( 'woocommerce_after_single_product_summary', 'woocommerce_output_related_products', 20);

    function woocommerce_output_related_products() {
        $output = null;

        ob_start();

        woocommerce_related_products(array(
            'columns' => 4, 
            'posts_per_page' => 4,
            '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
                )
            )
        )); 

        $content = ob_get_clean();
        if($content) { $output .= $content; }

        echo '<div class="clear"></div>' . $output;

    } 

Any help would be greatly appreciated,
Thanks.

Was it helpful?

Solution

There is another filter, woocommerce_related_products_args in /templates/single-product/related.php template file, that overrides your query array.

One possible solution is to override related.php template, create a new template and execute custom WP_Query there, then include that template with wc_get_template() function.

The other is to take advantage of built-in filters ( quite a number of them exists ). I'll try to explain that filters here, what is their purpose, and how to use them, in the order of their execution.


woocommerce_output_related_products_args

The first filter for setting the woocommerce_related_products() function arguments. The function loads related.php template and arguments passed are the global options for the template. Arguments are "posts_per_page", "columns" and "orderby".

/* An example of how to set the four products per page */
add_filter( 'woocommerce_output_related_products_args', function( $args ) 
{ 
    $args = wp_parse_args( array( 'posts_per_page' => 4 ), $args );
    return $args;
});


At the beginning of the template the WooCommerce $product object seeks the related products by category and tag. The result is an array of post ids that is later used for the post__in clause in main query. There are a few filters available.

woocommerce_product_related_posts_relate_by_category

It is used to exclude the related products by category.

add_filter( 'woocommerce_product_related_posts_relate_by_category', function() {
    return false;
});

woocommerce_product_related_posts_relate_by_tag

Exclude the related products by tag.

add_filter( 'woocommerce_product_related_posts_relate_by_tag', function() {
    return false;
});

woocommerce_product_related_posts_query

To make a final modification of the query parts.

add_filter( 'woocommerce_product_related_posts_query', function( $query ) {
    // modify $query array
    return $query;
});


The last filter that provides the possibility to modify the parameters for main query is woocommerce_related_products_args.

woocommerce_related_products_args

Since now the query is based on post__in clause, remove that part and add your custom query parts.

add_filter( 'woocommerce_related_products_args', function( $args ) 
{
    unset( $args['post__in'] );
    $args['tax_query'] = array( /* taxonomy parameters */ );
    return $args;
});

An example of how to display four related products relating to the tags.

add_filter( 'woocommerce_output_related_products_args', function( $args ) 
{ 
    $args = wp_parse_args( array( 'posts_per_page' => 4 ), $args );
    return $args;
});

add_filter( 'woocommerce_product_related_posts_relate_by_category', function() {
    return false;
});

A few tips that might be helpful:

In each filter hook, if you're not sure what are the default arguments passed in, simple use print_r on them to see the values in browser. Also, a look at the WooCommerce source files will clarify some things. And finally, a lot of times there is no need to completely override the default WooCommerce functions, since the creators of the plugin really made the effort with all those filters to make things easier.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top