Build A WordPress 2.8 Widget With The New Widget API

One of the main changes in WordPress 2.8 is the new widget API. This API is fully object oriented and provides the programmer all the necessary functions to create a WordPress widgets. Also, it now allows multiple use of each widget.

You can find the widget API in wp-includes/widget.php and the widgets itself in wp-includes/default-widgets.php. The class WP_Widget provides the functionality of the widgets, and each widget must be inherited. The class WP_Widget_Factory is for registration and instantiation of widgets responsible.

How to create a widget in WordPress 2.8?

It will be a simple example and will output the links for the RSS Feed of the articles and comments. In functions.php we first create the skeleton of our widgets:

class My_RSS_Widget extends WP_Widget {
	function My_RSS_Widget() {
		//Constructor
	}

	function widget($args, $instance) {
		// prints the widget
	}

	function update($new_instance, $old_instance) {
		//save the widget
	}
	
	function form($instance) {
		//widgetform in backend
	}
}
register_widget('My_RSS_Widget');

We have a class My_RSS_Widget created, which inherits the properties and methods of the WP_Widget class (extends). In a new widget, the methods widget and update always have to be created, form is optional. With register_widget ( 'My_RSS_Widget') will be the widget registered. Let's fill up our widget.

class My_RSS_Widget extends WP_Widget {
	function My_RSS_Widget() {
		$widget_ops = array('classname' => 'widget_rss_links', 'description' => 'A list with your feeds links' );
		$this->WP_Widget('rss_links', 'Feed links', $widget_ops);
	}

	function widget($args, $instance) {
		extract($args, EXTR_SKIP);

		echo $before_widget;
		$title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);
		$entry_title = empty($instance['entry_title']) ? ' ' : apply_filters('widget_entry_title', $instance['entry_title']);
		$comments_title = empty($instance['comments_title']) ? ' ' : apply_filters('widget_comments_title', $instance['comments_title']);

		if ( !empty( $title ) ) { echo $before_title . $title . $after_title; };
		echo '<ul id="rss">';
		echo '  <li><a href=" ' . get_bloginfo('rss2_url') . '" rel="nofollow" title=" ' . $entry_title . ' ">' . $entry_title . '</a></li>';
		echo '  <li><a href=" ' . get_bloginfo('comments_rss2_url') . '" rel="nofollow" title="  '. $comments_title . ' ">' . $comments_title . '</a></li>';
		echo '</ul>';
		echo $after_widget;
	}

	function update($new_instance, $old_instance) {
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		$instance['entry_title'] = strip_tags($new_instance['entry_title']);
		$instance['comments_title'] = strip_tags($new_instance['comments_title']);

		return $instance;
	}
	
	function form($instance) {
		$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'entry_title' => '', 'comments_title' => '' ) );
		$title = strip_tags($instance['title']);
		$entry_title = strip_tags($instance['entry_title']);
		$comments_title = strip_tags($instance['comments_title']);
?>
			<p><label for="<?php echo $this->get_field_id('title'); ?>">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 attribute_escape($title); ?>" /></label></p>
			<p><label for="<?php echo $this->get_field_id('entry_title'); ?>">Title for entry feed: <input class="widefat" id="<?php echo $this->get_field_id('entry_title'); ?>" name="<?php echo $this->get_field_name('entry_title'); ?>" type="text" value="<?php echo attribute_escape($entry_title); ?>" /></label></p>
			<p><label for="<?php echo $this->get_field_id('comments_title'); ?>">Title for comments feed: <input class="widefat" id="<?php echo $this->get_field_id('comments_title'); ?>" name="<?php echo $this->get_field_name('comments_title'); ?>" type="text" value="<?php echo attribute_escape($comments_title); ?>" /></label></p>
<?php
	}
}
register_widget('My_RSS_Widget');

RSS Widget Backend

The widget feature is for the output in the frontend to examine the update data and stores an instance of the widget and form creates in the backend the input mask, which in our case for the title of the widget and the displayed link text.

The code is self-explanatory. The function widget is for the output in the frontend responsible, update examine the data and stores an instance of the widget and form creates in the backend the input mask, which in our case for the title of the widget and the displayed link text.

RSS Widget frontend

So now implement your own ideas!

Please check out the post WordPress 2.8 Single Post Navigation Widget for a more advanced example.

Comments are closed.

54 comments

  1. Peter

    This is a great news. The old widget implemetation just didn't seem very well thought out, and it was pretty hard to use, especially if you wanted multiple instances of your widget. This is going to make things much better for everyone.

    Is there any backwards compatibility with this built into 2.8? While it is great news moving forward, there could be a lot of incompatible plugins for a while.

  2. Glenn Bennett

    Peter,

    I've created a tool that lets you wrap some php code in either the new 2.8 style widget or the existing widget style so it should be pretty easy to make a version for existing site as well as new sites. Please check out the tool at widgetifyr.com. Let me know how it works for you.

    Glenn

  3. ChaosKaizer

    Very helpful articles, I've a theme with multiple sidebar so 2.8 new widgets API will have it used.

    Cheers & thanks

  4. Josh

    Looks quite simple. Should be alot easier to create custom widgets now instead of hacking things together with the text widget.

    Thanks for the tutorial.

  5. pracas upreti

    great ,

  6. Jonathan

    @Peter, backwards compatibility seems ok so far for all the widgets I've used.

  7. Zack Katz

    @Jonathan - What about widgets coded using the new Widgets API working in previous versions? If I code a widget for 2.8, will it work in 2.7?

  8. Michael

    @Zack: No! That produces a fatal error. The classes doesn't exist.

  9. Zack Katz

    @Michael - That's what I figured. Is there a way that we can include the class in the widget download and say in PHP if class does not exist, include this file -- or is the code more spread out than 1 file?

  10. Zack Katz

    I see it's in wp-includes/widgets.php. Would code work like this:
    <?php if (!class_exists('WP_Widget')) {
    include('/path/to/class/wp-content/plugins/this-widget/widgets.php');
    } ?>

    I assume that would work....any reason why not?

  11. Michael

    Not tested:

    if (version_compare($wp_version, '2.8', '>=')) {
        class My_RSS_Widget extends WP_Widget {
        //code inside the class 
        }
        register_widget('My_RSS_Widget');
    }
    

  12. Christian Schenk

    @Michael: your snippet works as expected.

    There's a typo in the code above: inside the My_RSS_Widget class, line 10 inside the widget function - "wp $entry_title" should be "$entry_title".

    Anyway, thanks for the great post!

  13. Michael

    Thanks Christian! Fixed.

  14. P.Raman

    Can you please tell me how to create a widget to show a drop-down list of authors in a multi-author blog using the WP 2.8 widget API.

    I find that the default widgets have categories list but not author list.

    Thanks

  15. Michael

    @P.Raman: Nice idea. But it isn't done in five minutes.

  16. Philip M. Hofer (Frumph)

    How would I call that function" function widget($args, $instance) " ?

    in 2.5ish it was easy just to do and it would execute the function.

  17. Michael

    You don't have to call widget(). WordPress does it for you if the widget is active.

  18. Philip M. Hofer (Frumph)

    That's not what I asked, read it again.

  19. Philip M. Hofer (Frumph)

    I figured it out, my actual code execution that I would place inside the function widget() area I actually have *above* the class and called by function widget() {} .. call it My_RSS(){ ..

    Now if I go and hardcode it on the site someplace I can do that.

    - Phil

  20. TZS

    HI!

    Nice tut! But, i have a question. When i try to make a plugin by the above code, the WP has dropped an error, such as "register is not a member class" or something else like this...

    So how can i make a widget by the API in a plugin file? I have to use add_action() ot register_widget_controller() or what?

    Thanks for the help!

    TZS

  21. Michael

    TZS,
    with a plugin you can use

    add_action( 'widgets_init', create_function('', 'return register_widget("My_RSS_Widget");') );
    

  22. TZS

    tyvm! it works.

  23. Guillaume

    Not sure what I am doing wrong but I get this error:

    Warning: Missing argument 2 for WP_Widget::__construct(), called in \wp-includes\widgets.php on line 320 and defined in\wp-includes\widgets.php on line 93

    Great article by the way !

  24. Bryan Helmig

    If you get "Missing argument 2 for WP_Widget::__construct(), " make sure that you when you renamed your widget class that extends WP_Widget(), to name the function with the ops to same thing.

  25. Ben Chun

    If you run into problems like:

    PHP Fatal error: Call to a member function register() on a non-object in ../wp-includes/widgets.php

    You may need to adjust your registration code to wait until the WordPress init is completed, like this:

    function register_My_RSS_Widget(){
    register_widget('My_RSS_Widget');
    }
    add_action('init', 'register_My_RSS_Widget', 1)

  26. Ron Sparks

    amazing!!
    thanks so much.

    I also had an error like TZS
    and replacing:
    register_widget('My_RSS_Widget');

    with:
    add_action( 'widgets_init', create_function('', 'return register_widget("My_RSS_Widget");') );

    workd masterfully THANKS!

  27. Deryk Wenaus

    I had the same problem as Ron. This tutorial aslo explains it quite well:
    http://justintadlock.com/archives/2009/05/26/the-complete-guide-to-creating-widgets-in-wordpress-28

  28. Sitebase

    Good introduction to the new widget class Michael.
    Just a tip: You can replace the code in the update method with this:

    $instance = array_merge($old_instance, $new_instance)
    return array_map('strip_tags', $instance);

    This way it's less lines of code and you don't need to add code when you add new settings.

  29. MilanG

    Great article!

    I read many articles on this subject, but yours is first that mentioned where widget code should be placed. Thank you for that! I started freaking out. Like it's so obvious to beginner that it should go to functions.php.

  30. DavidM

    @Sitebaes:

    Wow, that's a wicked replacement.

    What about the widget form? Is there a simpler way you might advise for handling creating the form elements for the widget options?

  31. html5beta

    i try this in my function.php,works fine ,except sidebar widget panel cannot be draggable anymore.do someone know why?thank you.

23 pingbacks

  1. Creando Widgets con la nueva Widget API de Wordpress 2.8 | aNieto2K
  2. WP Links (5./6. April) - Link, WordPress, Artikel, Teil, Justin, Blog - CMPRESS
  3. Weekend Links - Apr 11, 2009 | OMNINOGGIN
  4. Are widgets easy enough now? - Fun with WordPress
  5. WordPress 2.8 for theme authors | The Theme Museum
  6. WordPress 2.8 Tips and Tricks Collection | Weblog Tools Collection
  7. links for 2009-06-10 - Macchianera
  8. WordPress 2.8 Baker: téléchargement et infos
  9. WordPress 2.8 Tips and Tricks | What’s UP
  10. WordPress 2.8 Tips and Tricks Collection | pc-aras
  11. WordPress 2.8: Features and tips — gunnerpress.com
  12. Extensive Wordpress 2.8 Getting Started Guide | tripwire magazine
  13. WordPress 2.8 Single Post Navigation Widget - WordPress 2.8 Widget API, form(), update(), widget() - dynamicinternet
  14. WordPress 2.8技巧 for 开发人员 | 帕兰映像
  15. Jungleland - Free WordPress Theme | Theme Lab
  16. Chris Coyier » Blog Archive » Things I Found Interesting Around September 3rd
  17. Tips & Guider till WordPress
  18. Adding Twitter to Wordpress « Blue Shrapnel on iliam
  19. 24 WordPress хака от WPEngineer Wordpress: статьи, плагины, темы
  20. Multi Widgets | Advanced Wordpress Tutorials
  21. 11 Awesome Wordpress Development Blogs
  22. Wordpress Widget Helper Class « Strx Blog
  23. Updates fürs Ari WordPress-Theme: Jetzt mit dunkler Theme-Version | Elmastudio