First I would like to apologize if this is off topic as it's based on Woocommerce and specific to a theme (Natural using wpOpal Themer), but the issue is a wordpress coding issue.

My theme has a "widget" so to speak that displays Woocommerce product categories based on custom criteria. The biggest problem with this is that it only shows the same categories and has no parameters to choose categories. I would like to change the behavior so that I get random categories. Searching around I found that I had to edit the woo_shop_category.php (through a child theme). I have found the snippet I need to change and using instructions and logic from - Categories and products in random order I have been able to get close to what I want.

Here is the problem. When I don't have the count as per the code below, it shows all categories in random order - the correct result.

  $product_cat = get_term_by( 'slug', $product_cat_slug, 'product_cat' );
$product_category_parent = $product_cat->term_id;

extract( $atts );

$_id = rand();
$_count = 0;

$args = array(
    'child_of'  => $product_category_parent,
'hide_empty'    => 1,
'hierarchical'  => 1,
'taxonomy'      => 'product_cat',
'pad_counts'    => 1,


$all_categories = get_categories( $args );
$_totals = count($all_categories);

As soon as I include 'number' => $number_cats in the args(a number of categories that is selected in the front end using King Composer as per the theme) it only shows the same categories as per the $number_cats value . For example, if I want 10 categories, it would shuffle the first 10 categories and does not display 10 random categories of all categories which is the desired action.

I doubt the following code is relevant but it basically tells to display each of the $all_categories as a carousel as per the woocommerce global variables.


<div class="opal-category-shop woocommerce <?php echo (($el_class!='')?' '.esc_attr( $el_class ):''); ?>">
    <div class="title"><span><?php echo trim($title);?></span></div>
    <div class="inner nopadding">
        <div class="products-collection owl-carousel-play woocommerce carousel-products" id="postcarousel-<?php echo esc_attr($_id); ?>" data-ride="carousel">
            <?php if( $_totals > $columns ): ?>
                <div class="carousel-controls  carousel-hidden hidden-xs">
                    <a href="#postcarousel-<?php echo esc_attr($_id); ?>" data-slide="prev" class="left carousel-control carousel-md">
                        <span class="fa fa-angle-left"></span>
                    <a href="#postcarousel-<?php echo esc_attr($_id); ?>" data-slide="next" class="right carousel-control carousel-md">
                        <span class="fa fa-angle-right"></span>
            <?php endif; ?>
            <div class="owl-carousel" data-slide="<?php echo esc_attr($columns);?>"  data-singleItem="true" data-navigation="false" data-pagination="false">
                <?php foreach($all_categories as $_category): ?>
                    <div class="cats-item">
                        <div class="image-category">
                            <a href="<?php echo esc_url( get_term_link( $_category->slug, 'product_cat' ) ); ?>">
                                    $thumbnail_id = get_woocommerce_term_meta( $_category->term_id, 'thumbnail_id', true );
                                    $image = wp_get_attachment_url( $thumbnail_id );
                                    if ( $image ) {
                                        echo '<img src="' . esc_url_raw( $image ) . '" alt="'.$_category->name.'" />';
                                        echo '<img src="'.esc_url( get_template_directory_uri() ) . '/images/cats-placeholder.png'.'" alt="'.$_category->name.'" />';

                        <div class="title-category"><a href="<?php echo esc_url( get_term_link( $_category->slug, 'product_cat' ) ); ?>"><?php echo trim($_category->name); ?></a></div>
                <?php endforeach; ?>

What I believe the issue is: The shuffle($all_categories); is doing its job and shuffling all the categories. But the shuffle is based on the count of categories and not on all categories. So basically I need to know how I can set my array to get all categories and shuffle them and then only display the number selected in $number_cats. So basically Array gets created and results shuffled. Then create another array from the results of the first array to the count of $number_cats.

Can I create two arrays that will first shuffle all categories and then choose the count from the shuffled categories? If that is the case, what is the syntax to create multiple arrays. I tried to list one array then create a variable from get_categories($args) and then create another array from that variable by calling it in the array as 'child_of' but that through a php error saying that it was illegal (I reverted after seeing this message. If need be I can recreate it if its required to troubleshoot)

1 Answer 1


While researching for this I came across Categories and products in random order which had a similar but different issue but was able to derive the required information to cut the array.

I modified his $categories = array_slice( $categories, 0, 5 ); to suit my needs. Final answer was just to add an array_slice based on $cat_number

so I modified $all_categories and called it just $categories (as I will later reference $all_categories) and changed the code to following

$categories = get_categories( $args );
$_totals = count($categories);
$all_categories = array_slice( $categories, 0, $number_cats );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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