How to Display Random Posts from Different Categories using WP_Query

Tutorials

In this WordPress tutorial we'll show you how to write a query that will output a random post from one of the top level categories in your site that is constantly changing.

banner image

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 randomize 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 screenshot 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:

Loading gist 98768e7f433d96c15433f2e0ac035e68

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:

Loading gist f452e808385e50df11e2e4eb828471fe

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:

Loading gist cab6d5d2ddb67bf0a6886ab48300de70

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:

Loading gist 1ec2ff430e77b81af08d041f803ac5c6

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

Loading gist 36be3cd37747f7056a3574fc1cfb5776

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:

Loading gist 4d6849a8b3fd1a88aaa7eb90e22d0ce8

The Finished Product

Your final code will look like this:

Loading gist 00eceabed297e8bbc6d56f417834dff4

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

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!

All the good WordPress stuff, once every two weeks

Subscribe

Leave a comment