Randomizing Posts in WordPress

Because query results end up cached in the object cache, it is difficult to use ‘orderby’=>’rand’ in a query. The first randomized result will then be cached and returned on each page reload until the cache is cleared. The solution to randomizing posts in WordPress is to add a filter to the theme’s functions.php file:

add_filter( 'the_posts', function( $posts, \WP_Query $query )
{
    if( $random = $query->get( 'pressable_random_posts' ) )
    {
        shuffle( $posts );
        $posts = array_slice( $posts, 0, (int) $random );
    }
    return $posts;
}, 10, 2 );

And then to the query add:

'pressable_random_posts' => 3

With 3 being the number of items you wish to display.


An example of a modified query:

$custom_args = array(
'post_type'      => 'products',
'post_status'    => 'publish',
'posts_per_page' => 20,
'orderby'        => 'rand',
'no_found_rows'  => true,
'pressable_random_posts' => 3
);

To apply a filter to a query without modifying the query directly, to your funtions.php file you can do something similar to:

function pressable_apply_filter_automatically($query) {

   if ( is_front_page()  &&  in_array ( $query->get('post_type'), array('products') ) ) {
       $query->set('pressable_random_posts', 3);
   }
}
add_action( 'pre_get_posts', 'pressable_apply_filter_automatically' );