I'm starting to go a little mad here, I must be missing something obious but I have tried many solutions.

My problem: I want to have 6 related products under each product. (Understanding if a category has more then 6 products in it)

I currently have the related products grabbing it's shared category. But when I load a product, it may show 1 related product, or 4, or 3. Every load its a different number of related products. Very odd.

Here is my code.

if ( ! defined( 'ABSPATH' ) ) {

global $product, $woocommerce_loop;

if ( empty( $product ) || ! $product->exists() ) {

if ( ! $related = $product->get_related( 6 ) ) {

$cats_array = array(0);

// get categories
$terms = wp_get_post_terms( $product->id, 'product_cat' );

// select only the category which doesn't have any children
foreach ( $terms as $term ) {
  $children = get_term_children( $term->term_id, 'product_cat' );
  if ( !sizeof( $children ) )
  $cats_array[] = $term->term_id;

$args = apply_filters( 'woocommerce_related_products_args', array(
  'post_type'            => 'product',
  'ignore_sticky_posts'  => 1,
  'no_found_rows'        => 1,
  'posts_per_page'       => 6,
  'orderby'              => $orderby,
  'post__in'             => $related,
  'post__not_in'         => array( $product->get_id() ),
  'tax_query' => array(
        'taxonomy' => 'product_cat',
        'field' => 'id',
        'terms' => $cats_array
) );

$products                    = new WP_Query( $args );
$woocommerce_loop['name']    = 'related';
$woocommerce_loop['columns'] = apply_filters('woocommerce_related_products_columns', 6);

If anyone has any advice that would be greatly appreciated. Thank you

3 Answers 3


You need to change the value of $orderby. Maybe the current value of $orderby is rand

'orderby'              => $orderby,

Now you need to change the value of **orderby => '' ** according to your need. for example

'orderby' => 'title'
'orderby' => 'menu_order title'
'orderby' => 'comment_count'
'orderby'   => 'meta_value_num'
'orderby'   => 'title menu_order'

Order & Orderby Parameters orderby (string | array) - Sort retrieved posts by parameter. Defaults to 'date (post_date)'. One or more options can be passed.

  1. 'rand' - Random order. You can also use 'RAND(x)' where 'x' is an integer seed value. Note an "order" parameter needs to be present for "orderby" rand to work.
  2. 'ID' - Order by post id. Note the capitalization.
  3. 'author' - Order by author. ('post_author' is also accepted.)
  4. 'title' - Order by title. ('post_title' is also accepted.)
  5. 'name' - Order by post name (post slug). ('post_name' is also accepted.)

More details https://codex.wordpress.org/Class_Reference/WP_Query


In some cases the RAND function may return an empty record.

For example, case you have "private" products you should remove them from the query output. So, for this case just add the line:

'post_status' => 'publish',


if you want to avoid writing code you can use this plugin which allows you to extrapolate all the related products for woocommerce based on your sorting and data preferences via the query builder. https://wordpress.org/plugins/dynamic-blocks-builder/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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