WooCommerce related products by tag

This is my first post written in English and I am a bit nervous, because I am not a fluent writer/speaker yet. However, as the main goal of this blog is improve my English, let’s start the game.

This tip is oriented to change the way of related products of WordPress / WooCommerce stores are displayed. By default, related products are shown from relations category of products. But, my client wanted to control the feature using Tags. To get that, we have to make some changes. Let’s see:

1) At the child theme functions.php, I added a new function. The comments are self explanatory.

term_id;

    // Get categories (removed / commented)
    /*
    $terms = wp_get_post_terms($id, 'product_cat');
    foreach ( $terms as $term ) $cats_array[] = $term->term_id;
     */

    // Don't bother if none are set
    if ( sizeof($cats_array)==1 && sizeof($tags_array)==1 ) return array();

    // Meta query
    $meta_query = array();
    $meta_query[] = $woocommerce->query->visibility_meta_query();
    $meta_query[] = $woocommerce->query->stock_status_meta_query();

    // 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
            )
        )
    ) ) );
    $related_posts = array_diff( $related_posts, array( $id ));
    return $related_posts;
}
add_action('init','get_related_custom');
?-->

2) After that, I copied the entire content of related.php (from theme > woocommerce > single-product > related.php) to a new file at child theme.

3) At last, I changed the call of function at related.php

a) of:

$related = $product->get_related($flatsome_opt['max_related_products']);

b) to:

$related = get_related_custom($product->id, $flatsome_opt['max_related_products']);

Voilá. It was easy, didn’t it? Now we have a new related products component that is filtered by tags.

See you later, with more articles about WordPress, Ruby on Rails and Django.

13 replies
  1. Duke
    Duke says:

    Simply magnificent! Great work and effort.

    It would be nice is you allow for the combination of both the tags and categories (but adding more weight to the tags –or– returning the tag matches first in terms of order).

    Would love to see this modification.

    Reply
  2. AJ
    AJ says:

    Hi, this solution seems to be not working anymore…

    In woocommerce related.php the line:
    $related = $product->get_related($flatsome_opt[‘max_related_products’]);
    Instead this is what I find:
    $related = $product->get_related( $posts_per_page );
    If I use:
    $related = get_related_custom($product->id, $flatsome_opt[‘max_related_products’]);
    WP Debug reports:
    Notice: Undefined variable: flatsome_opt
    Is it possible that a recent update of Woocommerce has changed how this works?

    Reply
  3. Edoc
    Edoc says:

    Hello evrybody, I need help here

    I want to display my related product just by tags no by category,
    this the code of related.php :

    exists() ) {
    return;
    }

    $related = $product->get_related( $posts_per_page );

    if ( sizeof( $related ) == 0 ) return;

    $args = apply_filters( ‘woocommerce_related_products_args’, array(
    ‘post_type’ => ‘product’,
    ‘ignore_sticky_posts’ => 1,
    ‘no_found_rows’ => 1,
    ‘posts_per_page’ => $posts_per_page,
    ‘orderby’ => $orderby,
    ‘post__in’ => $related,
    ‘post__not_in’ => array( $product->id )
    ) );

    $products = new WP_Query( $args );

    $woocommerce_loop[‘columns’] = $columns;

    $slide_config = array(
    ‘infinite’ => true,
    ‘slidesToShow’ => 4,
    ‘slidesToScroll’ => 1,
    ‘dots’ => false,
    ‘slide’ => ‘ul’,
    ‘responsive’ => array(
    array(
    ‘breakpoint’ => 1440,
    ‘settings’ => array(
    ‘slidesToShow’ => 4,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    ),
    array(
    ‘breakpoint’ => 992,
    ‘settings’ => array(
    ‘slidesToShow’ => 3,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    ),
    array(
    ‘breakpoint’ => 768,
    ‘settings’ => array(
    ‘slidesToShow’ => 2,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    ),
    array(
    ‘breakpoint’ => 480,
    ‘settings’ => array(
    ‘slidesToShow’ => 1,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    )
    )
    );

    if ( $products->have_posts() ) : ?>

    <div data-slider_config="” id=”related-products-carousel” class=”arexworks-slick-slider related products products-grid product-carousel”>
    have_posts() ) : $products->the_post(); ?>

    <?php endif;

    wp_reset_postdata();

    Reply
  4. Edoc
    Edoc says:

    NO THIS IS THE CODE BELOW.

    exists() ) {
    return;
    }

    $related = $product->get_related( $posts_per_page );

    if ( sizeof( $related ) == 0 ) return;

    $args = apply_filters( ‘woocommerce_related_products_args’, array(
    ‘post_type’ => ‘product’,
    ‘ignore_sticky_posts’ => 1,
    ‘no_found_rows’ => 1,
    ‘posts_per_page’ => $posts_per_page,
    ‘orderby’ => $orderby,
    ‘post__in’ => $related,
    ‘post__not_in’ => array( $product->id )
    ) );

    $products = new WP_Query( $args );

    $woocommerce_loop[‘columns’] = $columns;

    $slide_config = array(
    ‘infinite’ => true,
    ‘slidesToShow’ => 4,
    ‘slidesToScroll’ => 1,
    ‘dots’ => false,
    ‘slide’ => ‘ul’,
    ‘responsive’ => array(
    array(
    ‘breakpoint’ => 1440,
    ‘settings’ => array(
    ‘slidesToShow’ => 4,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    ),
    array(
    ‘breakpoint’ => 992,
    ‘settings’ => array(
    ‘slidesToShow’ => 3,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    ),
    array(
    ‘breakpoint’ => 768,
    ‘settings’ => array(
    ‘slidesToShow’ => 2,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    ),
    array(
    ‘breakpoint’ => 480,
    ‘settings’ => array(
    ‘slidesToShow’ => 1,
    ‘slidesToScroll’ => 1,
    ‘slide’ => ‘ul’,
    )
    )
    )
    );

    if ( $products->have_posts() ) : ?>

    <div data-slider_config="” id=”related-products-carousel” class=”arexworks-slick-slider related products products-grid product-carousel”>
    have_posts() ) : $products->the_post(); ?>

    <?php endif;

    wp_reset_postdata();

    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *