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!

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 byget_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:

And if I refresh the screen, it changes:

(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!