How to Display Random Posts from Different Categories using WP_Query

Sometimes you want to mix things up a little when displaying posts on your site, maybe by making the list random instead of just showing the last five posts like every other site in town.

The great news is that if you add a custom query to your page using the WP_Query class, you can do this by using a special argument that will randomise your posts.

And what if you want to take it a bit further and show random posts from a variety of categories on your site, making sure the posts aren’t duplicated if they happen to be in more than one category?

Again, it’s possible.

In this post I’ll show you how to write a query that will output a random post from one of each of the top level categories in your site, ensuring that not only is the list of posts random and constantly changing, it also reflects a wide cross-section of the content in your site.

Getting Started

To follow along with this post, you’ll need the following tools:

  • A code editor
  • A development installation of WordPress

You’ll also need to decide how you’re going to add your query. You could code it directly into a theme template file (such as your home page) or you could attach it to an action hook, if your theme has them. I’m going to use the development installation of my own site to demonstrate this, so I’ll add my code to the front-page.php template in my theme. Whatever method you choose, the code for the query will be the same.

Right now my home page looks like the screeenshot below, with some posts highlighted but not from every category. I’m going to add a list of random posts above the footer. It won’t look too pretty but it’s only my local development installation!

My site's home page

Fetching the Categories

The first thing is to fetch a list of categories. We could use the get_categories() function to do this, but in this case we just want to fetch the top level categories, otherwise things might get out of hand. For that, we use get_terms(), and use the parent value in its parameters.

Start with this code:

That will fetch each of the top level categories and then check if any are returned. If they are, it will open up a new section element, output a heading and run a foreach loop for each of them, so we can output a list of posts.

Setting up the Query

The next thing to do is to set up the query and define its arguments. We do this inside our foreach loop and use the $term variable already defined as one of the arguments for WP_Query.

Inside your foreach loop, add this:

That defines the arguments for the query:

  • the post type which is post,
  • the orderby, which is random,
  • the number of posts to be output, which is 1,
  • the category, which uses tax_query to set this as the slug of the term fetched by get_terms.

Running the Query and Loop

Now we have our query set up, let’s run it.

After your query arguments, and still inside the foreach loop, add this:

This outputs a list item with the title of the post and a link to it. You’ll now have a working list. But there’s a snag.

Avoiding Duplicates

Sometimes you’ll find that the query returns duplicate posts, if they’ve been added to more than one category. We need to fix that.

There are three lines of code we need to add. First, after the get_terms() function, add this code to define a new array of variables called $do_not_duplicate:

Next, add an extra argument to the query to ensure that posts in that array aren’t included:

And finally, after the line echoing out the post title in a list item, add the ID of the post which has just been output to that array:

The Finished Product

Your final code will look like this:

This shows you how the query goes inside the foreach loop and exactly where you need to add the code to avoid duplicates.

Let’s take a look at it on my site. Here’s my list:

A random list of posts, one from each category

And if I refresh the screen, it changes:

A second random list of posts, one from each category

(It’s highlighted some uncategorized posts – I need to fix that!)

A Random Query Is Fun and a Bit Different

Using random queries to output content from around your site gives your visitors an opportunity to find content from all of your categories. It also ensures that older posts, not just the most recent ones, are being displayed.

If you wanted to, you could include all of your categories or the subcategories of a particular top level category, by editing the get_terms() function. Or you could just use one category and output more random posts by editing the WP_Query class and removing the get_terms() function. The choice is yours!

Rachel McCollin
Do you have a creative way of randomizing content feeds from your blog? Tell us about it in the comments.