Making a widget to show a random post uses two underlying concepts you need to get familiar with to be good at WordPress development: making use of WP_Query
objects, and making widgets. If you’ve not checked them before, check out our Quick Guides which more thoroughly introduce both:
If you have, check out this video where I explain the pretty simple process I use to making a Random Post Widget:
How to Show Random Posts in WordPress
The core thing our widget will do is pull a random post from our WordPress database. (Specifically, we’ll be pulling posts whose post type is Post—that is, “blog posts” as opposed to Pages or any custom post type.)
Doing this requires us to use WP_Query
. If you’re new to that part of WordPress, you can learn all about it in our free course on using WP_Query
.
What makes pulling a random post possible is setting the query’s orderby
property to rand
. And here’s the full query:
$q_args = array(
'orderby' => 'rand',
'posts_per_page' => '1',
);
$query = new WP_Query( $q_args );
That’s the basics of how to query for a random WordPress post in the WordPress database. The rest of this demo will show you how to build out a widget with that behavior.
How to Make a Random Post WordPress Widget Step-by-Step
- Follow the steps listed in the first Quick Guide about widgets.
- At the start of the widget method, add the line
$query = new WP_Query
. This will create for you a new object,$query
, an instantiation of the WP_Query class (see the WP_Query link in further reading if that confuses you). - Add argument to the WP_Query line. That means to add to the line above so it now reads:
$query = new WP_Query( $q_args );
. Then you’ll also need to create the$q_args
variable. That’ll look like:$q_args = array( 'orderby' => 'rand', 'posts_per_page' => '1', );
What that does is create some arguments.
posts_per_page
makes ourWP_Query
only return one item.orderby => 'rand'
makes the function get a random one (by putting all of them into a random order). - Then we need to make a loop. What this means is that we need to use
while ($query->have_posts())
to contain a series of instructions. The first of those instructions will be$query->the_post()
which “primes” the post for us to access with functions likethe_title()
. Then we’re going to replace the display directions from the last post, so the title and excerpt of the post is shown. That leads to a block like this:echo $args['before_widget']; echo $args['before_title']; the_title(); echo $args['after_title']; echo get_the_excerpt(); echo $args['after_widget'];
- We make sure that after the end of the loop we call
wp_reset_postdata()
. This undoes our “pollution” in$query->the_post()
so that the rest of the site doesn’t act funky because of our widget. It’s just good hygiene.
Full Code for Making our Widget
class QG_Widget extends WP_Widget {
/**
* Sets up the widgets name etc
*/
public function __construct() {
$widget_ops = array(
'classname' => 'qg_widget',
'description' => 'This is a widget for a quick guide',
);
parent::__construct( 'qg_widget', 'Quick Guide Widget', $widget_ops );
}
/**
* Outputs the content of the widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
$q_args = array(
'orderby' => 'rand',
'posts_per_page' => '1',
);
$query = new WP_Query( $q_args );
while ($query->have_posts()) {
$query->the_post();
echo $args['before_widget'];
echo $args['before_title'];
the_title();
echo $args['after_title'];
echo get_the_excerpt();
echo $args['after_widget'];
}
wp_reset_postdata();
}
}
add_action( 'widgets_init', function(){
register_widget( 'QG_Widget' );
});
Further Reading on Widgets and WP_Query
If you’d like to learn more on the core technical elements of this demo, here are two of our free courses to check out—on using widgets and using WP_Query
, respectively:
Thanks for reading!
Thanks!
Works perfectly and makes sense. A lot of bad info on this on the internet out there on this topic.
Cheers