Output posts relating to the tags

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.

Answers


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.


Need Your Help

Skinning: Using a Color as StaticResource for another Color

wpf colors skinning resourcedictionary

I implemented skinning in my application. The application loads its Brushes.xaml resource dictionary which uses colors which reside in a skin-specific resource dictionary. So only one Color.xaml is

Is there an easy way to reload css without reloading the page?

javascript css stylesheet reload

I'm trying to make a live, in-page css editor with a preview function that would reload the stylesheet and apply it without needing to reload the page. What would be the best way to go about this?