Categories and products in random order

What I’m trying to do is getting Woocommerce categories and products randomly displayed on one page. The normal settings allow to display categories and products on the same page, but first come the categories and afterwards the products. This is the case because the categories come with the function woocommerce_product_subcategories() and afterwards the product loop starts.

What I want to to is something like this:

Read More
    $args = array(
    'post_type' => array('product', 'post'),
    'orderby' => 'rand', 
    'posts_per_page' =>-1,
    'post_status' => 'publish'
);

$query = new WP_Query($args);

but i have no clue how to get the categories in there.

to elaborate on my question:
i was able to randomize the output of the categories by adding:

shuffle( $product_categories );

to the function woocommerce_product_subcategories() or to be excact to the template i created, but i more or less copied the code from the function there

just thought that might help somebody, found it here: http://core.trac.wordpress.org/ticket/21875

but that is only a solution for just the categories or as metioned above, if the categories are shown before the products they will be shuffeled, but of course still not with the products


ok, inspired by @s_ha_dum answer i manged to get a solution:

//this 1. part is out of the woocommerce-template.php and part of the woocommerce_product_subcategories()
$product_cat = get_term_by( 'slug', $product_cat_slug, 'product_cat' );
$product_category_parent = $product_cat->term_id;

$pcat_args = array(
'child_of'  => $product_category_parent,
'hide_empty'    => 1,
'hierarchical'  => 1,
'taxonomy'      => 'product_cat',
'pad_counts'    => 1
);
$product_categories = get_categories( $pcat_args  );

//grab things by post_type product
$prod_args = array(
'post_type' => array('product'),
'orderby' => rand, 
'posts_per_page' =>-1,
'post_status' => publish
);
$ng_query = get_posts($prod_args);

//combines, merge the arrays
$merge_query = array_merge( $ng_query, $product_categories );

//make the order random
shuffle($merge_query);

//iterate merged arrays
foreach( $merge_query as $mqp ) { 
setup_postdata($mqp);
if ( $mqp->taxonomy == product_cat ) {
echo $mqp->category_nicename;
echo "<br/>";
} else {
echo $mqp->post_title;
echo "<br/>";
}
}

this gives me a randomized list of categories and products!

like @s_ha_dum said it is neccessray to differ between the arrays/object-types merged together. i did that, for this simplified solution, by checking for taxonomy – not sure if that is a good way for more complex outputs.

(1st) EDIT: i now implemented it with all the specific formating and its still working well – so looking for the taxonomy »product_cat« is a good solution for my scenario!

(2nd) EDIT: i ran into the problem that the price and the add-to-cart-button wouldnt show up and the iteration would break, the solution for that was to add setup_postdata(); – i added that into the code above

Related posts

Leave a Reply

2 comments

  1. as suggested by kaiser, my last working edit as solution:

    ok, inspired by @s_ha_dum answer i manged to get a solution:

    //this 1. part is out of the woocommerce-template.php and part of the woocommerce_product_subcategories()
    $product_cat = get_term_by( 'slug', $product_cat_slug, 'product_cat' );
    $product_category_parent = $product_cat->term_id;
    
    $pcat_args = array(
    'child_of'  => $product_category_parent,
    'hide_empty'    => 1,
    'hierarchical'  => 1,
    'taxonomy'      => 'product_cat',
    'pad_counts'    => 1
    );
    $product_categories = get_categories( $pcat_args  );
    
    //grab things by post_type product
    $prod_args = array(
    'post_type' => array('product'),
    'orderby' => rand, 
    'posts_per_page' =>-1,
    'post_status' => publish
    );
    $ng_query = get_posts($prod_args);
    
    //combines, merge the arrays
    $merge_query = array_merge( $ng_query, $product_categories );
    
    //make the order random
    shuffle($merge_query);
    
    //iterate merged arrays
    foreach( $merge_query as $mqp ) { 
    setup_postdata($mqp);
    if ( $mqp->taxonomy == product_cat ) {
    echo $mqp->category_nicename;
    echo "<br/>";
    } else {
    echo $mqp->post_title;
    echo "<br/>";
    }
    }
    

    this gives me a randomized list of categories and products!

    like @s_ha_dum said it is neccessray to differ between the arrays/object-types merged together. i did that, for this simplified solution, by checking for taxonomy – not sure if that is a good way for more complex outputs.

    (1st) EDIT: i now implemented it with all the specific formating and its still working well – so looking for the taxonomy »product_cat« is a good solution for my scenario!

    (2nd) EDIT: i ran into the problem that the price and the add-to-cart-button wouldnt show up and the iteration would break, the solution for that was to add setup_postdata(); – i added that into the code above

  2. You should be able to combine the categories and the products array/objects and then shuffle them, and then loop through the combined array/object. Problems I’d expect:

    1. One might be an object and the other an array so you’d have to cast one or the other.
    2. The format of the two parts might be different so as you loop through you’d have to check at each iteration whether the item is a product or a category and switch the display function accordingly.

    Otherwise, it shouldn’t be too hard. I think it would be trickier to pull it with the query as you were contemplating.