Display Random Posts from Specific Tags or Categories in WordPress
When developing the colorful Quintessential Theme (opens in new tab), I initially planned on displaying five random posts from each of my most popular tags and categories in the super-slick sliding-panel sidebar. Because I am running an older version of WordPress, however, this task proved to be quite the educational experience.
In newer versions (from 2.5 I think) of WordPress, the query_posts()
function enables users to display posts in random order using the orderby=rand
parameter. This would have made my life easy, as I could have included the following code for each of my random post lists:
<ul class="random-posts">
<?php query_posts('tag=whatever&showposts=5&offset=0&orderby=rand'); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</li>
<?php endwhile; endif; ?>
</ul>
This would have been great, but the random-post ordering doesn’t work for my particular version of WordPress. As it turns out, for older versions of WordPress that are missing the incredibly useful orderby=rand
parameter for the query_posts()
function, there is an unofficial plugin available in the WordPress Help Forums that imparts the orderby=rand
functionality to the query_posts()
function, thereby enabling users of pre-2.5 versions of WordPress to implement their own random post loops.
For those of you who would like to setup some random post loops on your own site, here’s how to do it in two easy steps. (Remember, this is only necessary if the above method does not work for your particular version of WordPress.)
Numero Uno: Upload and activate the plugin
Copy & paste the following code into a file named “random-posts.php
” (or whatever), upload it to your /wp-plugins/
directory, and activate it via the Plugins panel in the WordPress Admin:
<?php
/*
Plugin Name: Random Posts Query
Description: Imparts random display functionality to posts generated via
query_posts in older versions of WordPress (especially great for version 2.3)
Author URI: http://wordpress.org/support/topic/70359?replies=3#post-444323
*/
// usage: include "random=true" as a parameter in your query_posts loop
function query_random_posts($query) {
return query_posts($query . '&random=true');
}
class RandomPosts {
function orderby($orderby) {
if (get_query_var('random') == 'true')
return "RAND()";
else
return $orderby;
}
function register_query_var($vars) {
$vars[] = 'random';
return $vars;
}
}
add_filter('posts_orderby', array('RandomPosts', 'orderby'));
add_filter('query_vars', array('RandomPosts', 'register_query_var'));
?>
Numero Dos: Include and customize the template code
Once the plugin is in place, create multiple tag-specific and category-specific random-post lists by placing the following code after the main loop in your theme template file (e.g., the sidebar.php
file):
<ul class="random-posts">
<?php // use tag=whatever or category_name=whatever for cat/tag-specific posts ?>
<?php query_posts('tag=whatever&showposts=5&offset=0&random=true'); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</li>
<?php endwhile; endif; ?>
</ul>
Before uploading, make sure you customize this code according to your needs. Old heads feel free to knock the boots, while newer chaps may benefit from the following information:
- As mentioned in the code comments, replace the “
tag=whatever
” parameter with the name of the tag for which you would like to display random posts. - To display random posts from a specific category instead of a specific tag, simply replace the
tag=whatever
parameter withcategory_name=whatever
and change the name to your chosen category. - Adjust the other
query_posts
parameters as needed to accomplish your post-display goals. For example, you may also want to display the post excerpt for each post item by including thethe_excerpt()
tag. - Note that this code is essentially the same as that given for newer versions of WordPress; the only difference being that you use the
orderby=rand
parameter for newer versions of WordPress (where the plugin is not required), andrandom=true
for older versions (where the plugin is required). - Placing additional
query_posts()
loops after the main loop may result in unintended paging and/or plugin issues, so make sure to place it after the main loop. - To create multiple lists of random posts, simply create multiple instance of this loop and change the category or tag parameter names to suit your needs.
Time to chill
That concludes this brief retro-tutorial. Although it may not be of much use to those treading the perpetual “upgrade” treadmill, it will hopefully provide some relief for randomizing posts in older WordPress versions.
27 responses to “Display Random Posts from Specific Tags or Categories in WordPress”
what is happening is that there is a loop inside my
sidebar.php
that fetches a post from a category.when I add some debug code to output
is_single()
andis_category()
I find thatis_single()
is true before the start of that sidebar loop and at the start of the loop it goes to false andis_category()
becomes true. That remains that way so that when thewp_footer()
code is executed it still has false foris_single()
and true foris_category()
.The loop code in my sidebar that seems to cause this is set up by calling
query_posts(array(
'showposts' => 1,
'cat' => $cp_pC,
'category__not_in' => array($ar_headline,$ar_featured),
'post__not_in' => $ar_ID,
));
I tried putting
$temp_query = clone $wp_query ;
in front of it , and$wp_query = clone $temp_query;
after I finished using the loop , but it doesnt seem to work.I cant figure out why it doesn’t work. :-(
Ok, got a bit further. My original theme had in the sidebar the loop on cathegories and then all sidbar widgets. With this setup, and I go to a single post, in the footer
is_single()
resolves to true. Then I moved some of the widgets (Latest Comments, Latest Posts) to the sidebar before the cathegory loop and thenis_single()
in the footer resolves to false.So now the only question remains. How can I ‘force’
is_single()
back to false?Yes, found it, it was in the codex all along.
http://codex.wordpress.org/Function_Reference/wp_reset_query
So the thing to remember is :
whenever you create a custom query, after that , call to to ‘This function destroys the previous query used on a custom Loop. Function should be called after The Loop to ensure conditional tags work as expected.’
so, now I got to go and talk to my theme vendor about not being able to solve this ;-)
@ddeconin: Glad to hear you got it worked out. Thanks for documenting the process for the benefit of other readers.
Woot. Thanks for this. Was a huge help.
I implemented this on a single.php page, for to show some Random Posts from the same category. When I did this, I noticed it’d occasionally suck in the current post I was on, so I edited the query a bit, and just wanted to share it incase anyone else was looking for the same solution.
Just added ‘
post__not_in
’ in the array. Simple but easy to miss if you are a newbie and don’t know what to search for.<?php query_posts(array(
'category_name' => 'wallpapers',
'showposts' => 4,
'offset' => 0,
'orderby' => 'rand',
'post__not_in' => array($post->ID),
)); ?>
Thanks Ricky – awesome tip! :)
Not sure if anyone is checking this anymore, but thought I might try.
I’d like to sort the random posts. I know, sounds counter-intuitive, but what I’ve got is a query that pulls 2 random posts from a category (like what you have above) but I want those 2 posts to be displayed in descending order, so that the newest of the 2 random posts is above the older. Make sense? Know how I can do it? Many thanks in advance.
Yes someone is checking this :)
Have you tried including the
order
parameter in the query? More info here:WP Codex: Order & Orderby Parameters
Many thanks for your reply! In fact I have tried using it, and I think part of the problem is that random has a hard time playing nicely with the
order
parameter. I used:<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args= array(
'orderby' => 'rand',
'order' => 'desc',
'posts_per_page' => 2,
'category_name' => 'home-in-a-flash',
'paged' => $paged
);
query_posts($args);
?>
And at first I thought it was working, but upon refreshing a few times, I found my old problem (older post showing before newer post).
Thought perhaps I might need a nested loop but not sure. Any ideas? Thanks again for your reply :)
I would try the same query using
WP_Query
, which is generally a better way of doing it. Here is an example:$query = new WP_Query(array(posts_per_page' => 5, 'orderby'=>'rand', 'order'=>'DESC'));
while ($query->have_posts()) : $query->the_post();
...
endwhile;
wp_reset_postdata();
More info here:
http://codex.wordpress.org/Class_Reference/WP_Query
Thanks so much Jeff. I wasn’t successful getting it to work, but I really appreciate you taking the time to give me tips.