Build A WordPress 2.8 Widget With The New Widget API
April 6th, 2009 by Michael • WordPress Tutorials • 54 Comments
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');

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.

So now implement your own ideas!
Please check out the post WordPress 2.8 Single Post Navigation Widget for a more advanced example.
Info
- Published in WordPress Tutorials
- Tags: Widget, Widget API, WordPress, wp2.8
- Comment feed
- read: 77726 | today: 13
- leave a Comment
31 Comments
23 Pings
- Creando Widgets con la nueva Widget API de Wordpress 2.8 | aNieto2K
- WP Links (5./6. April) - Link, WordPress, Artikel, Teil, Justin, Blog - CMPRESS
- Weekend Links - Apr 11, 2009 | OMNINOGGIN
- Are widgets easy enough now? - Fun with WordPress
- WordPress 2.8 for theme authors | The Theme Museum
- WordPress 2.8 Tips and Tricks Collection | Weblog Tools Collection
- links for 2009-06-10 - Macchianera
- WordPress 2.8 Baker: téléchargement et infos
- WordPress 2.8 Tips and Tricks | What’s UP
- WordPress 2.8 Tips and Tricks Collection | pc-aras
- WordPress 2.8: Features and tips — gunnerpress.com
- Extensive Wordpress 2.8 Getting Started Guide | tripwire magazine
- WordPress 2.8 Single Post Navigation Widget - WordPress 2.8 Widget API, form(), update(), widget() - dynamicinternet
- WordPress 2.8技巧 for 开发人员 | 帕兰映像
- Jungleland - Free WordPress Theme | Theme Lab
- Chris Coyier » Blog Archive » Things I Found Interesting Around September 3rd
- Tips & Guider till WordPress
- Adding Twitter to Wordpress « Blue Shrapnel on iliam
- 24 WordPress хака от WPEngineer Wordpress: статьи, плагины, темы
- Multi Widgets | Advanced Wordpress Tutorials
- 11 Awesome Wordpress Development Blogs
- Wordpress Widget Helper Class « Strx Blog
- Updates fürs Ari WordPress-Theme: Jetzt mit dunkler Theme-Version | Elmastudio




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.
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
Very helpful articles, I've a theme with multiple sidebar so 2.8 new widgets API will have it used.
Cheers & thanks
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.
great ,
@Peter, backwards compatibility seems ok so far for all the widgets I've used.
@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?
@Zack: No! That produces a fatal error. The classes doesn't exist.
@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?
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?
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'); }@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!
Thanks Christian! Fixed.
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
@P.Raman: Nice idea. But it isn't done in five minutes.
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.
You don't have to call widget(). WordPress does it for you if the widget is active.
That's not what I asked, read it again.
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
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
TZS,
with a plugin you can use
add_action( 'widgets_init', create_function('', 'return register_widget("My_RSS_Widget");') );tyvm! it works.
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 !
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.
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)
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!
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
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.
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.
@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?
i try this in my function.php,works fine ,except sidebar widget panel cannot be draggable anymore.do someone know why?thank you.