I've moved! I've moved my online home to mikejolley.com, and thats where I'll be blogging primarily. This site will stay live for archive purposes :)

Create a WordPress Recent-Posts Widget

May 17, 2007 | Published in: Wordpress & plugins | Tags: , , , , , , 38

Wordpress WidgetsWidgets 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.

Added widget

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

Settings

In action it looks like this:

In action

Lazy mans corner

For a full code listing, click here

Download it all zipped up below.

Download My Recent posts widget Version 1.1

Enjoy

I hope my little tutorial on widget creation was of a great help :)

Found this post useful? Why not buy me a coffee!

Related Entries

38 Responses to “Create a WordPress Recent-Posts Widget”

RSS feed for comments on this post.

  1. 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

  2. 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

  3. 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:

    1
    2
    
    <?php if ( !function_exists('dynamic_sidebar')
            || !dynamic_sidebar() ) : ?>

    Then you add a new file in your theme called functions.php with something like this inside it:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <?php
    if ( function_exists('register_sidebar') )
        register_sidebar(array(
            'before_widget' => '',
            'after_widget' => '',
            'before_title' => '<div class="title">',
            'after_title' => '</div>',
        ));
    ?>

    And your good to go!

    Comment made on May 17, 2007 at 9:26 am

  4. Jonathan says:

    Awesome tutorial Mike, thanks for sharing : ).

    -Jonathan

    Comment made on May 17, 2007 at 2:50 pm

  5. 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

  6. Mike Jolley says:

    Comment made on May 17, 2007 at 4:28 pm

  7. Mike Cherim says:

    Thanks :)

    Comment made on May 17, 2007 at 5:51 pm

  8. Anthony Brewitt says:

    Your right on that^

    Comment made on May 29, 2007 at 2:48 pm

  9. 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

  10. 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

  11. 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

  12. 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

  13. 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

  14. 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

  15. 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

  16. 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

  17. 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).'"&gt;
    <strong>'.$post-&gt;post_title.'</strong></a>';

    if ($excerpt) echo ''.strip_tags($post-&gt;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

  18. 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

  19. 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

  20. 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

  21. 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

  22. 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

  23. 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

  24. 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

  25. 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.'&amp;category=' . $category . '&amp;exclude=' . $exclude);

    Comment made on November 11, 2007 at 7:07 pm

The comments are closed.

About this site

Blue Anvil is the online web design journal & portfolio of , a web designer from Norfolk, England. Read More »
MiniCard Theme for WordPress
  • Featured work - More

    • Beefjack
    • Integrity
    • theotaku.com
  • Latest Tweet - More

    • @pippinsplugins Thanks. We're rewriting all those queries anyway (queryposts uh oh)
  • Out of the blue - More

    • Download Monitor 3.3.5 Tagged for release

      The latest update to Download Monitor for WordPress has been released; this version comes with a many fixes and some new features, such as improved sorting. For full details view the readme; you can grab the plugin here.

    • Closing the Forums

      Just posting to let current users know that I’m closing the forum on Blue-Anvil. This is mainly due to spam-registrations getting out of hand and being a general nuisance. I will be posting good topics as FAQ items within posts if applicable.

      Please note that you can still post and get help for my plugins/themes by posting on the wordpress.org website.

    • Show off your MiniCard!

      Are you a user of the WordPress MiniCard theme? Its been downloaded over 14,000 times so far!

      If you have used it as-is, made your own child-theme or done something creative with it, please show off your MiniCard’s in the comments, I’d love to see how the theme is being used!

    • Spam Stopper updated for WordPress 3.0

      My Spam Stopper plugin has been updated for WordPress 3.0 (version 3.1.3) – you can grab it here. Sorry this update took longer than my other plugins but this one gets less lovin’ – if you want to change that feel free to donate, spread the word, or rate it on the WordPress.org plugin page.