Create a Wordpress Recent-Posts Widget
Widgets are a cool new feature built into wordpress version 2.2, and allow you to drag mini plugins into your widget-enabled theme’s sidebars.
They have all kinds of uses, searches, polls, you name it.
This article will show you how to create a customisable Recent post widget for yourself.
Step 1 – Creating the file
First create a file called myRecentPosts_widget.php, you can call it what you like really, as long as you know what it is. Open it up in your favorite text/code editor.
Lets start by adding the ‘php’ tag and some information about the author:
1 2 3 4 5 6 7 8 | <?php /* Plugin Name: My Recent Posts widget Description: Adds a sidebar widget to display posts from a specified category Author: Mike Jolley, jolley_small@tesco.net Version: 1.0 Author URI: http://blue-anvil.com */ |
Done that? Well done, lets move on.
Step 2 – The widget function begin
Next we need to add the widgets functionality. Lets add the start of our function: the init function, which will wrap all our plugin functionality. We will also add a little code to make sure widgets are enabled (and the widget functions exist), to avoid errors:
1 2 3 4 | function widget_myRecentPosts_init() { if ( !function_exists('register_sidebar_widget') ) return; |
Now we can start adding our widgets functionality, the next code creates our function and gets variable values (some of these we will set later).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function widget_myRecentPosts($args) { // "$args is an array of strings that help widgets to conform to // the active theme: before_widget, before_title, after_widget, // and after_title are the array keys." - These are set up by the theme extract($args); // These are our own options $options = get_option('widget_myRecentPosts'); $title = $options['title']; // Title in sidebar for widget $show = $options['show']; // # of Posts we are showing $excerpt = $options['ex']; // Showing the excerpt or not $exclude = $options['exclude']; // Categories to exclude if ($show<1) $show = 1; if ($exclude=="") $exclude = "0"; |
The next piece of code will start outputting to the screen, using the default $args, and our widget title.
1 2 | // Output echo $before_widget . $before_title . $title . $after_title; |
Step 3 – The Posts Query
The next code starts pulling results from the database using queries. This is more complex, so don’t worry if it confuses you!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // GET POSTS global $wpdb; $sql = 'select DISTINCT * from '.$wpdb->posts.' INNER JOIN (select * from '.$wpdb->post2cat.' INNER JOIN '.$wpdb->categories .' ON '.$wpdb->post2cat.'.category_id = '.$wpdb->categories .'.cat_ID) as A ON '.$wpdb->posts.'.ID = A.post_ID WHERE (A.cat_ID NOT IN ('.$exclude.')) AND '.$wpdb->posts.'.post_status="publish" AND '.$wpdb->posts.'.post_type="post" GROUP BY ID ORDER BY '.$wpdb->posts.'.post_date DESC LIMIT 0,'.$show.';'; $posts = $wpdb->get_results($sql); |
The above query gets all posts that are published, not excluded (from one of our options), and orders them by date, limiting the number queried to another of our options.
The next piece of code checks if we had any results, and starts looping to output them in the sidebar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // start list echo '<ul>'; // were there any posts found? if (!empty($posts)) { // posts were found, loop through them foreach ($posts as $post) { // format a date for the posts $post->post_date = date("F j, Y",strtotime($post->post_date)); // if we want to display an excerpt, get it/generate it if no excerpt found if ($ex) { if (empty($post->post_excerpt)) { $post->post_excerpt = explode(" ",strrev(substr(strip_tags($post->post_content), 0, 100)),2); $post->post_excerpt = strrev($post->post_excerpt[1]); $post->post_excerpt.= " [...]"; } } //output to screen echo '<li> <a class="post" rel="bookmark" href="'.get_permalink($post->ID).'"><span class="inner"> <strong class="title lifestyle">'.$post->post_date.' - '.$post->post_title.'</strong>'; if ($ex) echo '<br />'.strip_tags($post->post_excerpt); echo '</span></a></li>'; } } else echo "<li>No recent Posts</li>"; // end list echo '</ul>'; |
That was a lot, but its commented so read through to get a better understanding of how the rows are outputted. To finish our function we just close the function (and output the closing element of the widget).
1 2 3 | // echo widget closing tag echo $after_widget; } |
Step 4 – Creating the settings
Widgets make it easy to create a small settings dialog for your widget, our widget is going to get settings for:
- Widget title
- posts to show
- whether or not to show excerpt
- Categories to exclude from the list
Lets get started. We declare our settings function, and load the variables.
1 2 3 4 5 6 7 8 | // Settings form function widget_myRecentPosts_control() { // Get options $options = get_option('widget_myRecentPosts'); // options exist? if not set defaults if ( !is_array($options) ) $options = array('title'=>'Recent Posts', 'show'=>'5', 'excerpt'=>'1','exclude'=>''); |
Next we check if the settings form has been posted, updating the settings if it has.
1 2 3 4 5 6 7 8 9 10 | // form posted? if ( $_POST['recentArticles-submit'] ) { // Remember to sanitize and format use input appropriately. $options['title'] = strip_tags(stripslashes($_POST['recentArticles-title'])); $options['show'] = strip_tags(stripslashes($_POST['recentArticles-show'])); $options['excerpt'] = strip_tags(stripslashes($_POST['recentArticles-excerpt'])); $options['exclude'] = strip_tags(stripslashes($_POST['recentArticles-exclude'])); update_option('widget_myRecentPosts', $options); } |
So we have handled posted options, now we need a form! Lets get the options to show in the form by default.
1 2 3 4 5 | // Get options for form fields to show $title = htmlspecialchars($options['title'], ENT_QUOTES); $show = htmlspecialchars($options['show'], ENT_QUOTES); $excerpt = htmlspecialchars($options['excerpt'], ENT_QUOTES); $exclude = htmlspecialchars($options['exclude'], ENT_QUOTES); |
Now we can happily display the form. Notice we only need to write the fields, the widgets engine handles the form code!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // The form fields echo '<p style="text-align:right;"> <label for="myRecentPosts-title">' . __('Title:') . ' <input style="width: 200px;" id="myRecentPosts-title" name="myRecentPosts-title" type="text" value="'.$title.'" /> </label></p>'; echo '<p style="text-align:right;"> <label for="myRecentPosts-show">' . __('Show:') . ' <input style="width: 200px;" id="myRecentPosts-show" name="myRecentPosts-show" type="text" value="'.$show.'" /> </label></p>'; echo '<p style="text-align:right;"> <label for="myRecentPosts-excerpt">' . __('Show excerpt:') . ' <input style="width: 200px;" id="myRecentPosts-excerpt" name="myRecentPosts-excerpt" type="text" value="'.$excerpt.'" /> </label></p>'; echo '<p>Enter the categories to exclude below, this must be a comma separated list of category id\'s!</p>'; echo '<p style="text-align:right;"> <label for="myRecentPosts-exclude">' . __('Exclude:') . ' <input style="width: 200px;" id="myRecentPosts-exclude" name="myRecentPosts-exclude" type="text" value="'.$exclude.'" /> </label></p>'; echo '<input type="hidden" id="myRecentPosts-submit" name="myRecentPosts-submit" value="1" />'; } |
And thats that for settings!
Step 5 – Register the widgets
The last piece of code registers the widget for use. After that were done.
1 2 3 4 5 6 7 8 9 10 11 | // Register widget for use register_sidebar_widget(array('My Recent Posts', 'widgets'), 'widget_myRecentPosts'); // Register settings for use, 300x100 pixel form register_widget_control(array('My Recent Posts', 'widgets'), 'widget_myRecentPosts_control', 300, 200); } // Run code and init add_action('widgets_init', 'widget_myRecentPosts_init'); ?> |
Widget armed
Now its finished, upload to plugins directory, activate it, then go to the widgets control panel (under the presentation tab of the wordpress admin) and drag it into one of your sidebar widget sections.

Click the little form icon on the widget to bring up the settings form

In action it looks like this:

Lazy mans corner
For a full code listing, click here
Download it all zipped up below.
Enjoy
I hope my little tutorial on widget creation was of a great help
Found this post useful? Why not buy me a coffee!











Anthony Brewitt says:
Just wanted to add for all those widget newbies that a widget is basically the same as a plugin but is easier to implement via drag and drop etc. You can give yout WP theme Widgets by downloading the Automatic Widget Plugin.
Comment made on May 17, 2007 at 8:39 am
Will says:
Nice article. With my sites custom theme would I be able to use widgets by just installing the Automatic Widget Plugin, or would it be more complicated?
Comment made on May 17, 2007 at 9:16 am
Mike Jolley says:
Hey Ant, actually you don’t need the plugin with wordpress 2.2., its built in.
WIll – Either upgrade to 2.2 or install the plugin. Then you just need to add a small chunk of code in the sidebar of your theme, read here http://automattic.com/code/widgets/themes/ e.g:
Then you add a new file in your theme called functions.php with something like this inside it:
And your good to go!
Comment made on May 17, 2007 at 9:26 am
Jonathan says:
Awesome tutorial Mike, thanks for sharing : ).
-Jonathan
Comment made on May 17, 2007 at 2:50 pm
Mike Cherim says:
Nice Mike. Question for you: How are you managing the color codes in your pre boxes? Normally when I want to do that I present code in a *.phps file, but I wouldn’t know how to implement that in something that’s included in a post etc.
Comment made on May 17, 2007 at 4:12 pm
Mike Jolley says:
A plugin – http://wordpress.org/extend/plugins/wp-syntax/
Comment made on May 17, 2007 at 4:28 pm
Mike Cherim says:
Thanks
Comment made on May 17, 2007 at 5:51 pm
Anthony Brewitt says:
Your right on that^
Comment made on May 29, 2007 at 2:48 pm
Nathan Snipes says:
Great article. I downloaded your file for use on my blog because I wanted the ability to exclude a few categories from the Recent Posts section.
It seems to work great with one small exception: it lists each post twice!
Has anyone else had an issue with this? Any one know what might be causing this?
Comment made on June 24, 2007 at 2:33 am
Nathan Snipes says:
Upon further investigation the problem seems to be with how many categories a post is filed under.
For example, if Post1 is filed under Category1 and Category2 it will be listed twice. If Post1 is filed under Category1, Category2 and Category3 it will be listed 3 times, etc.
I’ve looked through the code but I’m not really sure what I should be looking for. Can someone help?
Comment made on June 24, 2007 at 3:31 am
Mike Jolley says:
Ive updated the download and code listings to deal with that issue, thanks.
Comment made on June 25, 2007 at 10:44 pm
Francesco says:
Hi
really nice tutorial and cool widget. I have done some modifications to have the beginning of the excerpt when rolling over the link. I don´t know much php, so I was wondering how can I change the call for the post-date to use the global locale settings (in my case italian) rather than the default english used by php.
I was looking at using the setlocale variable, but I was unable to get it to work. Any suggestion? Thanks /F
Comment made on July 16, 2007 at 1:26 pm
Francesco says:
Nevermind. I got that sorted
If anyone is interested in the changes i made you can go to http://www.francescoinsvezia.net/?p=364. Thank you Mike!
Comment made on July 16, 2007 at 2:28 pm
Lair says:
Thanks for this great tutorial, I coded my first plugin with it : A simple “add to my google page” button with a customizable link
Comment made on July 27, 2007 at 10:39 pm
komakai says:
I d/l the widget. Uploaded, and activated. error followed:
WordPress database error: [You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'select * from wp_post2cat INNER JOIN wp_categories ON wp_po]
select DISTINCT * from wp_posts INNER JOIN (select * from wp_post2cat INNER JOIN wp_categories ON wp_post2cat.category_id = wp_categories.cat_ID) as A ON wp_posts.ID = A.post_ID WHERE (A.cat_ID NOT IN (0)) AND wp_posts.post_status=”publish” AND wp_posts.post_type=”post” GROUP BY ID ORDER BY wp_posts.post_date DESC LIMIT 0,5;
Comment made on July 29, 2007 at 11:00 pm
Mike Jolley says:
if your using mysql below v4.1 then it does not support nested selects
Comment made on July 29, 2007 at 11:09 pm
Luis Olmos says:
Love the widget, but is there a way to include a picture?
1. Say all posts with pictures have the image at the beginning of the text. What needs to be done so that it displays the title then the pic (resized by either the script or the css) and then the text?
I’ve already fiddled around with your code so that it displays only the post title as the link and the text is put in a tag.
echo '<a>ID).'">
<strong>'.$post->post_title.'</strong></a>';
if ($excerpt) echo ''.strip_tags($post->post_excerpt);
echo '';
i just cant figured how to do get the pic to load.
2. if i want 2 instances of the widget displaying a separate category how do I modify the source file? I’ve changed the name of the widget and instances within it, wordpress sees it loads it but on the widget bar i can load it but i have no options.
Thanks for this great plugin/widget!!!
Comment made on August 16, 2007 at 1:27 pm
Patrick says:
Thanks for the widget but how do I exclude the date with only the post title shown?
Comment made on September 17, 2007 at 10:35 am
Joel Bergqvist says:
I would also like to use the widget twice at the same time (two intances) How is this done?
Comment made on September 18, 2007 at 8:27 am
alex says:
This version is not compatible with WP 2.3 – wp_post2cat no longer exists
Comment made on September 30, 2007 at 1:49 am
fadi says:
hi there,
thank you for this tutorial.
is it possible to customise this widget using css?how?
Comment made on October 3, 2007 at 8:51 am
alias says:
how to plug this code anywhere in the page i don’t like widgets personally is there a ?
Comment made on October 16, 2007 at 3:14 pm
Alex says:
Hey Mike,
since the plugin is not compatible with WP 2.3 are you planning to upgrade the plugin? It would be very sad if it’s not usable in the future
Thanks
Alex
Comment made on October 23, 2007 at 4:24 pm
Ellen says:
I’m interested in adding to this widget an indication of how many comments a post has received… i.e,
Debugging (Tuesday, Sep 18)
Why doesn’t everyone just get a Mac? (7 comments)
but am not sure what code to add to the widget or where to add it.
Comment made on November 4, 2007 at 6:25 pm
Justin says:
Thanks for putting together a great plugin, Mike. I made a few changes to suit my own needs, and in the process updated it to work with 2.3.
@Alex – To make this widget 2.3 ready, you can just replace the wpdb calls with something like:
global $post;$posts = get_posts('numberposts='.$show.'&category=' . $category . '&exclude=' . $exclude);
Comment made on November 11, 2007 at 7:07 pm