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. Carlo says:

    Hello. Im’ sorry but your link
    http://blue-anvil.com/downloads/myRecentPosts.php.txt
    returns
    “A file permissions error has occurred. Please check the permissions on the script and the directory it is in and try again.”

    Comment made on November 29, 2007 at 12:02 pm

  2. Fareeha says:

    Excellent! I have modified the functionality to create another widget. I was actually confused at some points. You have clarify my confusion. Thanks a lot.

    Comment made on June 8, 2008 at 8:17 am

  3. Marlon Maulsby says:

    nice tutorial, how would i allow multiple instances of this widget?

    Comment made on July 21, 2008 at 2:54 am

  4. test says:

    test

    Comment made on February 11, 2009 at 10:23 am

  5. James says:

    Great widget.

    Is there any way I can add a recent posts widget to display recent posts on my static home page?

    Any help please email me

    Thanks

    Comment made on February 16, 2009 at 5:38 pm

  6. regalos originales says:

    You now what? some people would say fire is cold…

    Comment made on March 3, 2009 at 11:35 pm

  7. regalos originales says:

    Where should I paste the code?

    Comment made on March 3, 2009 at 11:53 pm

  8. tashweb says:

    you need to add functionality

    Comment made on March 3, 2009 at 11:58 pm

  9. KFGD63 says:

    Hey Man,

    Thanks for your useful tutorial regarding registration widget.

    Regarding the (Zip File) download, after downloading where i will put it?

    Thanks in advance for your reply.

    Ciao

    KFGD63

    Comment made on March 19, 2009 at 1:16 pm

  10. Faisal Khan says:

    For me this didn’t work.

    I used therefore this code instead of your snippet where you assess the database. It uses function and do not assess the database.
    // GET POSTS
    $r = new WP_Query(array('showposts' =&gt; $show, 'what_to_show' =&gt; 'posts', 'nopaging' =&gt; 0, 'post_status' =&gt; 'publish', 'caller_get_posts' =&gt; 1));
    if ($r-&gt;have_posts()) :
    ?&gt;

    have_posts()) : $r-&gt;the_post(); ?&gt;
    &lt;a href=""&gt; </a>

    &lt;?php
    // echo widget closing tag
    echo $after_widget;

    wp_reset_query(); // Restore global post data stomped by the_post().
    endif;

    Comment made on March 26, 2009 at 1:32 am

  11. Exam Philippines says:

    thank for you for sharing this tutorial on how to create recent post. god bless!!!

    Comment made on March 28, 2009 at 5:48 pm

  12. Administrare Damien says:

    Excelent job, thanks!

    Comment made on May 15, 2009 at 9:39 pm

  13. Obrazy says:

    great tutorial, thanks!

    Comment made on May 28, 2009 at 7:57 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 »
ThemeSlice
  • Featured work - More

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

    • Would be nice is people showed more love for MiniCard by rating it on wordpress.org http://wordpress.org/extend/themes/minicard
  • Out of the blue - More

    • MiniCard 1.1.7 Update

      I have just uploaded 1.1.7 of MiniCard here and to the WordPress theme directory. This updates includes:

      • New networks; xing, gowalla, yelp, foursquare, mobileme, google buzz
      • A way to change link text and define multiple links of the same network
      • A way to define your own custom links + icons
      • Improved admin panel

      Hope you like it, and don’t forget you can show your support by purchasing the premium pack from here.

    • Switched: From Shared to VPS

      It’s been about two weeks now since I made the transition from a shared reseller hosting account to a VPS (Virtual Private Server) account – impressions so far, excellent performance but fiddly to configure.

      The reason I wanted to change from shared hosting was the fact the server was always being hacked (even though ALL my scripts were secure), there was frequent downtime, support blamed me for problems every time, and it was slow as hell.

      Those used to a shared hosting environment would probably not know where to start when faced with configuring a VPS. Luckily, a lot of it was pre-configured when I received my account – certainly some of the major security holes were patched. I was not satisfied with those however. As a victim of hacking in the past (previous host swears it was not there fault, something I don’t believe) I took extra care to secure it as a much I could – configuring brute force detection, the firewall, installing mod security (excellent rules for that here: http://www.atomicorp.com/wiki/index.php/Atomic_ModSecurity_Rules) and going though multiple guides (like this one: http://www.webhostingtalk.com/showthread.php?t=468168) with a fine-tooth comb.

      The result? My pages are loading at least 6 times faster, I have had no down time (or at least have not noticed any), and I feel in control and happy. No longer am I at the mercy of shared hosts :)

      If your interested, I chose ServInt as my provider as they offered a great deal, as well as being a managed service (so I’m not on my own if I screw things up). I was tempted by the bells and whistles of Media Temple, but felt the ServInt service was better value.

    • Download Monitor 3.2.2 Maintenance Release

      Download Monitor has received some more love and has been updated. Here’s the change log from the new version:

      • Small bugfix in uploader.php – cat ID
      • Changed stats graph calculation – thanks lggemini
      • Changes to headers in download.php to avoid caching
      • File Browser fixes – $root was clashing with something….
      • exclude_cat works in all sections of download_page now
      • Removed hardcoding of /uploads/
      • Added action to download.php – should be able to use it to stop a download if you want – maybe limiting downloads per day or something? Whatever you want…
      • Made it so if you post new file on ‘edit’ screen, the post date is updated.
      • Fixed the ‘blank meta’ section which blanks out custom field values when nothing is set.
      • Moved ‘allow_url_fopen’ check.
      • Someone said downloads don’t work with spaces in the name. They do! Wasting my time sonny…
      • All work and no play make jolley a dull boy
      • Had to rename capabilities so they work. Apologies if you have to set this up again! Cheers to Mark Dingemanse.
      • {category_ID} custom format tag added. Useful if you want to send someone to its category on the DL page I guess. Also added {category_other} so when no category is set “other” is shown – this is because the download page can show an ‘other’ section if you want it to.
      • You can now manually edit the post date on the edit download screen.

      If you have edited capabilities for download monitor user permissions, you’ll have to again sorry! This is because I named them too long. Also, you should check your forced downloads still work because there was a logic error meaning they may not have been forced after-all…

      Enjoy.

    • Mahousive update to Download Monitor (3.2)

      Today I completed the update for the Wordpress Download Monitor Plugin – many tweaks, fixes, and features added. There were no changes to the database structure so people upgrading should be fine. Here is the list from the change log:

      • {user} tag added for custom formats
      • ‘autop’ option fix
      • Download page buttons applied with CSS so they are easier to customise/translate.
      • Fix for pagination bug after editing a download
      • Category output fix on edit downloads screen
      • Category urls on download page use ID rather than name to prevent errors when cats have the same names.
      • exclude_cat added to download_page shortcode
      • Localised ‘hits’ ‘date’ ‘title’ on download page
      • Option to disable the download logging
      • Read file ‘chunked’ some people found large files were corrupted so this should help (fingers crossed)
      • Added show_tags option to download page – displays x amount of tags on the download page.
      • File Browser root setting and download.php logic/mime types modified thanks to Jim Isaacs (jidd.jimisaacs.com)
      • Interface Improvements
      • Bulk edit categories, custom fields, tags, member only downloads
      • Added roles for download monitor admin – should be able to use with a role manager plugin if you want anyone other than admin to access the admin section e.g. http://wordpress.org/extend/plugins/capsman/
      • Change redirect after add
      • Edit Cat names/parents
      • Dedicated tags and thumbnails fields (they still use meta table though)

      And yes, those category link bugs are fixed at long last, and you can edit category names finally. Phew!