Creating Custom WordPress Widgets

With each new version of WordPress, the argument whether or not it qualifies as a CMS gets a little quieter.

In the WordPress core we have widgets, custom fields, custom taxonomies, and with version 2.9, an expansion of get_post_type. Add a few plugins and all sorts of post-types and custom write panels become a reality.

All this functionality is great so long as you, the developer, implement it in a way that is tough to break. Because once in the hands of the client, anything goes.

Flexible Layout

Then there is the issue of layout. For clients, moving content from one column to the other can be a technical hurdle, particularly for dynamic sites which rearrange content frequently to satisfy advertisers, audience demands, and so on.

Default drag-and-drop widgets are a great part of our arsenal, but adding your own custom widgets can really make life simpler for both developer and client.

Example Custom Widgets

In the quest to give more control to end users, Pro Theme has been experimenting with more custom widgets. Check out the demo for themes like The Local and Elemental for examples.

the local theme

Below are widgets we’ve started including with most themes, including Mimbo Pro:

  • Google Adsense. In the control panel you enter your Adsense ID and the widgets display ads accordingly. Works in any of the standard block sizes.
  • Community Tweets. Aggregates Twitter activity according to location latitude/longitude. Contains fields for Number of Tweets and Mile Radius.
  • Latest Tweets. Contains fields for Username and Number of Tweets
  • Post Author Details. Contains author avatar, date and comments feed.
  • Upcoming Posts. Displays a list of future-dated posts.
  • More from this Author. For single-post pages. Displays five headlines from the same author.
  • More from this Category. For single-post pages. Displays five headlines from the same category.
  • Print Preview. Uses javascript to render the page print-friendly and free of images.
  • Share This. Lets you post the current page to Twitter, StumbleUpon, Digg, Delicious and Facebook.
  • YouTube. Displays a featured video with fields for Embed Code and Description
  • Map Your Location. A Google Maps widget with fields for Location, Zoom Amount and Type of Map View (Roadmap, Satellite or Terrain).
  • Popular Posts. Displays five headlines of most-commented posts.
  • Subscribe to Feed. Includes an RSS icon and feed link.

We’ve gotten tons of great feedback from users who rely on positioning Google Adsense blocks and want to adjust their content accordingly. In the case of The Local, the entire homepage is 90% widgetized, with four columns to configure. Not to mention writers in the hyperlocal space who write unique content, but also rely on aggregating from other sites and social media sources.

How Do Custom Widgets Work

At the simplest possible level, custom widgets are implemented by 1) creating a class, and 2) registering a new widget. Forget about functionality within the widget for a moment and look at the basic setup which you would paste inside functions.php:

class My_Widget extends WP_Widget {
	function My_Widget() {
		parent::WP_Widget(false, 'Our Test Widget');
	}
function form($instance) {
		// outputs the options form on admin
	}
function update($new_instance, $old_instance) {
		// processes widget options to be saved
		return $new_instance;
	}
function widget($args, $instance) {
		// outputs the content of the widget
	}
}
register_widget('My_Widget');

That’s it. We can now visit our widgets panel to confirm:

custom widget

Adding editable functionality into our widget is another story. Using the “Popular Posts” widget as an example, my partner Ben Gillbanks will walk us through creating the rest.

Creating a “Popular Posts” Widget

Firstly we have to name the widget class. I prefix my functions and classes with bm_ (Binary Moon) as it means there will never be any clashes with other functions and plugins.

We can then name the widget in the constructor, which is the first function, and it should have the same name as the class. This will be called when the class is first created and it defines the name you see in the widget editor.

Next up, I create the last method which is a form function which defines what data can be editable within the widget. In this case, it’s simply the title of the widget to be displayed on the blog. The update method can often remain as it is, although you may want to do some data validation (make sure the data input is safe/ allowed).

Then finally, the widget method. This is where the widget itself is displayed. You’ll notice I am actually passing the arguments to another function that is elsewhere in the theme. The reason I do this is because I like to split the display out separately so that I can use the function directly in the theme without widgets as well.

Notice the $args parameter in the widget method. These args are actually the arguments you pass to the register sidebar method, before_widget, after_widget etc. You can read more about these and creating custom widgets on the WordPress Codex Widget API page.

Here is the final code:

<?php
class bm_widget_popularPosts extends WP_Widget {

	function bm_widget_popularPosts() {
		parent::WP_Widget(false, 'Popular Posts');
	}

	function widget($args, $instance) {
		$args['title'] = $instance['title'];
		bm_popularPosts($args);
	}

	function update($new_instance, $old_instance) {
		return $new_instance;
	}

	function form($instance) {
		$title = esc_attr($instance['title']);
?>
		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></label></p>
<?php
	}
 }
function bm_popularPosts($args = array(), $displayComments = TRUE, $interval = '') {

	global $wpdb;

	$postCount = 5;

	$request = 'SELECT *
		FROM ' . $wpdb->posts . '
		WHERE ';

	if ($interval != '') {
		$request .= 'post_date>DATE_SUB(NOW(), ' . $interval . ') ';
	}

	$request .= 'post_status="publish"
			AND comment_count > 0
		ORDER BY comment_count DESC LIMIT 0, ' . $postCount;

	$posts = $wpdb->get_results($request);

	if (count($posts) >= 1) {

		if (!isset($args['title']) {
			$args['title'] = 'Popular Posts';
		}

		foreach ($posts as $post) {
			wp_cache_add($post->ID, $post, 'posts');
			$popularPosts[] = array(
				'title' => stripslashes($post->post_title),
				'url' => get_permalink($post->ID),
				'comment_count' => $post->comment_count,
			);
		}

		echo $args['before_widget'] . $args['before_title'] . $args['title'] . $args['after_title'];
?>

		<ol>
<?php
		foreach ($popularPosts as $post) {
?>
			<li>
				<a href="<?php echo $post['url'];?>"><?php echo $post['title']; ?></a>
<?php
			if ($displayComments) {
?>
			(<?php echo $post['comment_count'] . ' ' . __('comments', BM_THEMENAME); ?>)
<?php
			}
?>
			</li>
<?php
		}
?>
		</ol>

<?php
		echo $args['after_widget'];
	}
}
?>

Further Uses for Custom Widgets?

Clients frequently need special notifications and other dynamic bits to display on their site with minimal setup. What other content that’s frequently handled via plugins would make a great custom widget?

Note: This post has also been translated by a reader into Belorussian
  • http://wpscoop.com Stuart

    Thanks for posting this tutorial Darren, fantastic information and well presented as always. Using custom widgets for a client project is always my preferred option.

    • http://mahunneysfarm.com Mikel

      Great tutorial. For all those who couldn’t get the popular posts example to work as published, you need to correct the syntax error on line 46 and register the widget by adding

      register_widget(‘bm_widget_popularPosts’)

  • Michael Montgomery

    This Tutorial makes me want to try my hand at custom widgets, nice work !!

    THANKS

  • Dhaval Jani

    Thanks for a detailed and easy to follow tutorial!

    • http://accessorieshandphone.joseph-phantom.com/ steven

      i agree with you it’s really nice work
      thanks a lot

  • Pingback: Creating Custom WordPress Widgets | Darren Hoyt Dot Com | ePortals

  • http://www.kevinleary.net Kevin

    Hey Darren,

    Thanks for the mention, I’m honored. Keep up with the killer designs. I especially love the blog overview page you’ve designed.

    Thanks!

  • Pingback: 6 Tips For Creating Book Club Discussion Questions For Your Book and Other Book Marketing Tips | Largestore Blog

  • http://www.jauhari.net/ Jauhari

    Wonderful Tricks, I will try it

    • http://www.senegalfrauds.com/ Liutongbao

      Great job, Thank you! Now I am learning to creat my own widgets~

  • Pingback: How To Create Custom Widgets # WordPress Tricks & Tips

  • Pingback: Around the WordPress Community: WPMU Merger, Widgets, Custom Fields, Shortcodes | WordCast - Blogging news, WordPress help, WordPress plugins, WordPress themes, WordPress news

  • Karen

    Hi,
    Great Information!!
    On your ‘The Local’ site how are you processing the featured post with the image in the middle? Is this a special widget?

    Thanks
    Karen

    • Darren

      Yep, Featured Content is just another custom widget that pulls the latest story and whatever image is attached.

      • Karen

        I have been trying to hunt around and find this widget with no luck. Any chance you tell me where to find it?

        Thanks
        Karen

        • Darren

          It’s included with The Local theme. If you open your widgets panel you’ll see it.

  • http://stephanielane.com/chapelhill/chapel_hill_real_estate.html Chapel Hill Houses for Sale

    Thank you for your refreshing article.
    It was a pleasure reading it. Look forward to more articles from you!

  • http://www.kucukaydin.com küçükaydın

    it is good, i want to tried but i had a error :(

  • http://www.extremehost.ba/ registracija domene

    Thank you for your wonderful post. Very informative and I enjoyed reading it along with your other articles. Thanks for sharing and continue the great work.

  • http://www.extreme.ba/ izrada stranica

    This is great article! Thanks for share this!

  • shahab

    i try that with WP 2.9.2 but it doesnt show any in user side of site however it has been showed in widget area

  • http://livestreamfree.net/ andee

    good…like this….very help me..

  • http://newsbuzzy.com Newsbuzzy

    thanks for sharing…very good tutorial

  • Pingback: Creating widgets in WordPress | DevReference.org

  • http://www.mcm.co.ba Adi

    Hello Dearen, I have just read full article and I must admit its was of great specially because in my job I use WordPress Widgets a lot so thank you very much and keep up the good work!!

  • http://wordpress.themeshq.net Wordpress Themes

    Wow, I cant believe the whole site is literally made with widgets! I think after reading this article, it really isnt that hard to make a widget! Hopefully, I can make one that have as much features as your site.

  • http://www.idcreate.net Affordable Web Design Edinburgh

    thanx for this tutorial I keep working on wordpress as well.
    I need to say that your site is first class for user friendlyness and a design

  • http://www.snilesh.com neel

    excellent article. I am planing to create one new plugin and want to learn how to create widgets. your article help me alot while creating this plugin. thanks for this article.

  • yk

    Your examples does not work with WordPress 3.0
    I was able to get the final code to be seen as a plugin by WP 3.0 by inserting this header

    /*
    Plugin Name: TEST
    Plugin URI: http://etc.com
    Description: blah blah
    Version: 1.00
    Author: test boy
    Author URI: http://etc.com
    */

    but when i tried to activate it, I got the following error code
    Parse error: parse error in D:\Web\voivod.net\wp-content\plugins\voivodtwitter\functions.php on line 73

    also, inserting this header in the first barebones example code, doesn’t work..

  • ed

    dear mr hoyt,

    i’ve been following your site more than other sites which wp is the main content.
    those sites are few months to a year old vs. your site and i believe you are one of the ‘foundation’ of wordpress (for being one of the few who have been sharing info about wp).

    but i think you missed one thing along the way. you have not published a book yet (or did you?).

    i wish you could have time to publish a kick-ass wordpress book. theme design, plugin dev’t, and so on.

    throwing my coin to the wishing well now…

  • http://www.diyetlerim.net Diyet

    I have just read full article and I must admit its was of great specially
    because in my job I use WordPress Widgets a lot so thank you very much and keep up the good work!!

    excellent article..Thanks

  • http://ozapps.com.au Australian Iphne Apps

    I have just read full article and I must admit its was of great specially because in my job I use WordPress Widgets a lot so thank you very much and keep up the good work!!

  • Maha

    Its really working.I searched this for one day.It was really good and usefull one.I learned how to create it.
    Thank u.

  • http://www.matbaarehberi.net matbaa rehberi

    excellent article. I am planing to create one new plugin and want to learn how to create widgets. your article help me alot while creating this plugin. thanks for this article.

  • http://www.dugundavetiyesi.tk düğün davetiyesi

    excellent article. thanks for this article.

  • http://www.ekisilanlari.net ek iş ilanları

    excellent article. thanks for this article.

  • http://www.sinavhaftasi.com sınav sonuçları

    excellent article. thanks for this article.

  • http://www.seo-backlinking.com Seo Community

    A whole site based on widgets!!! That sure is amaizing considering how limitations a widget could have. Great post. Please keep providing such informations

  • Pingback: Web Publishing Group » Blog Archive » Custom Widget? No Problem

  • http://www.nikahsekeri.net nikah şekeri

    excellent article. thanks for this article.

  • http://www.muzungu.pl konradk

    great tutorial, but it wasnt warking for me. :) i tried add this to my plugin, even i copied exact your code and it doesnt workd. i saw blank page.

    i dont know if something was changed in wordpress since you wrote this tutorial, or maybe it depends if you create widget in functions.php or in plugin, but i found SOLUTION.

    in my case i had to not to call function register_widget() directly but pack it in action hack ‘widgets_init’. and after this everything work ok :)

  • Dan Romanchik

    I used this post to create my own custom widget. Worked great!!

    I do have a question, though. How do get WP to display a text description of this widget. I have the code:

    function SmallPic_Widget() {
    parent::WP_Widget(false, ‘Sidebar Picture Widget’);
    }

    and this displays “Sidebar Picture Widget” as both the title and description of the widget.

    Thanks, Dan

  • http://www.idcreate.net Cheap Web Design Edinburgh

    fantastic tutorial
    Thanks for share this!

  • http://moonpixel.com/ moonpixel

    Thanks a lot for detailed explanation, got a custom widget working in no time thanks to your post!!

  • http://www.seasky-light.com Led Tube Light

    Good example,thank you
    Protecting the earth,Loving our world,Starting From here—-
    Led Tube Light, Led Panel Light, T8 Led Tube , Led Flood Light, Led Grow Light
    Car AC Parts, Car AC Hose,
    LV包包, Gucci包包, Bally男包

  • http://hulinar.ru Хулинар

    Useful post and nice clear code, thxx

  • http://www.fixedshop.net Chris Fixie

    The new kind of custom post types are awesome too! I just saw a website from New Zealand with people using them to create games.

  • http://www.wordpress-gr.org Ελληνική Κοινότητα WordPress

    Very nice article ! We thank you very much about this article.

  • http://www.anlikaltinfiyatlari.com altın fiyatları

    excellent article. thanks for this article…thank you.Very nice article ! We thank you very much about this article…

  • R.dloin

    thanks for sharing…

  • Pingback: 20 More WordPress Code Snippets and Hacks | Wbcom Designs | VAPDI

  • Pingback: 20 More WordPress Code Snippets and Hacks | Preukson

  • http://www.arakablosu.com/ erkan

    thanks for sharing…
    thank u

  • http://www.novolines.net Novolines

    Exactly what I was looking for… gonna digg a little deeper into coding, customizing makes the whole thing a lot more fun :)

  • Pingback: 20 More WordPress Code Snippets and Hacks | Wpfail.com

  • http://www.canliradyodinle.tv radyo dinle

    yhanks good sharing

  • Pingback: Creating Custom WordPress Widgets - 5 Hour Developer

  • http://www.sagive.co.il Sagive

    10x a lot darren..

    Hmm.. getting an error trying this on
    unexpected ‘{‘ on line 57..

    Only me ?

  • Acee Baba

    Great article. Thanks for sharing