In this tutorial, I will teach you how to
create a Hello World sidebar widget using the WordPress 2.8 widget API.
I will provide the code throughout this post, and also provide the
examples for download at the end of the post.
WordPress 2.8 Widget API
In this tutorial, I will teach you how to create a Hello World
sidebar widget using the WordPress 2.8 widget API. I will provide the
code throughout this post, and also provide the examples for download
at the end of the post. This example will be demonstrated on the
Default WordPress theme and provide two configurable lines of text that
can be modified.
There are three main functions that every widget must include. These functions include widget(), update(), and form() and are each responsible for a different part of the widget. Let’s take a brief look at each function.
widget()
/**
* Displays the Widget
*
*/
function widget($args, $instance){
extract($args);
$title = apply_filters('widget_title', empty($instance['title']) ? ' ' : $instance['title']);
$lineOne = empty($instance['lineOne']) ? 'Hello' : $instance['lineOne'];
$lineTwo = empty($instance['lineTwo']) ? 'World' : $instance['lineTwo'];
# Before the widget
echo $before_widget;
# The title
if ( $title )
echo $before_title . $title . $after_title;
# Make the Hello World Example widget
echo '<div style="text-align:center;padding:10px;">' . $lineOne . '<br />' . $lineTwo . "</div>";
# After the widget
echo $after_widget;
}
The widget() function will be the first function we
delve into. This function is responsible for displaying the widget. The
above function was created for the Hello World example. This function
will always require two parameters, $args and $instance.
$args contains the native WordPress variables for the widget that some themes use to ensure the widget is used properly. extract($args); creates those variables, such as $before_widget, $before_title, $after_title, and $after_widget. These are important to include to ensure that all themes will be compatible with your widget.
$instance is the instance of your widget that is
currently being passed to the function. WordPress 2.8’s widget API adds
the ability to have multiple instances of each widget. $instance is an array that will store all of your widget’s configurable options, which in this case is $title, $lineOne, and $lineTwo.
It is important to note that when calling for each option, you should
use an if statement to ensure that if the string was empty that the
default will be used. This may not be necessary for each element so use
desecration when doing this, but it can be useful when you do not want
a certain value to be left empty. Another important thing to note is
that there are certain WordPress values that WordPress will use
differently. For instance, $title has a special filter applied because it is the title of the widget which WordPress recognizes.
update()
/**
* Saves the widgets settings.
*
*/
function update($new_instance, $old_instance){
$instance = $old_instance;
$instance['title'] = strip_tags(stripslashes($new_instance['title']));
$instance['lineOne'] = strip_tags(stripslashes($new_instance['lineOne']));
$instance['lineTwo'] = strip_tags(stripslashes($new_instance['lineTwo']));
return $instance;
}
update() is by far the simplest of the three functions. All update() does is save the values of each of the configurable options for the widget.
The update() function takes two different parameters, $new_instance and $old_instance. These variables are rather self explanatory. The old instance($old_instance) is overwritten by the new instance($new_instance) which values are taken from the widget form.
Always be sure to include the proper PHP functions such as strip_tags() and stripslashes() to ensure that no matter what a user puts in the widget options, they will not break the page the widget appears on.
form()
/**
* Creates the edit form for the widget.
*
*/
function form($instance){
//Defaults
$instance = wp_parse_args( (array) $instance, array('title'=>'', 'lineOne'=>'Hello', 'lineTwo'=>'World') );
$title = htmlspecialchars($instance['title']);
$lineOne = htmlspecialchars($instance['lineOne']);
$lineTwo = htmlspecialchars($instance['lineTwo']);
# Output the options
echo '<p style="text-align:right;"><label for="' . $this->get_field_name('title') . '">' . __('Title:') . ' <input style="width: 250px;" id="' . $this->get_field_id('title') . '" name="' . $this->get_field_name('title') . '" type="text" value="' . $title . '" /></label></p>';
# Text line 1
echo '<p style="text-align:right;"><label for="' . $this->get_field_name('lineOne') . '">' . __('Line 1 text:') . ' <input style="width: 200px;" id="' . $this->get_field_id('lineOne') . '" name="' . $this->get_field_name('lineOne') . '" type="text" value="' . $lineOne . '" /></label></p>';
# Text line 2
echo '<p style="text-align:right;"><label for="' . $this->get_field_name('lineTwo') . '">' . __('Line 2 text:') . ' <input style="width: 200px;" id="' . $this->get_field_id('lineTwo') . '" name="' . $this->get_field_name('lineTwo') . '" type="text" value="' . $lineTwo . '" /></label></p>';
}
The final piece of the trifecta, form(), is used to
display the form that is used on the WordPress admin interface when
creating the widget. This form should include the proper input options
for each configurable setting for the widget. It is important to note,
WordPress now provides both the Save and Remove buttons natively, and
it is not necessary to code in those buttons.
This function should also include an array of default values which
will be used to populate the form the first time the widget is called
in the WordPress admin interface.
WordPress 2.8 now has two different functions that are used in conjunction with the form. get_field_name() and get_field_id()
will provide you will the correct field names and ids for each
configurable option. This code is necessary in order to enable multiple
instances of your widget.
If you are developing a plugin to be used in multiple languages, you
must provide localization support by encapsulating your text with __( ).
I don’t want to get into localization, so if you are planning on
working with multiple languages you will need to look that up.
Piecing It All Together
So you have the three new functions and you are ready to make your
widget a reality. Let’s take a look at the beginning of the Hello World
example widget.
<?php
/*
* Plugin Name: Hello World Example
* Version: 1.0
* Plugin URI: http://jessealtman.com/2009/06/08/tutorial-wordpress-28-widget-api/
* Description: Hello World example widget using the the WordPress 2.8 widget API. This is meant strictly as a means of showing the new API using the <a href="http://jessealtman.com/2009/06/08/tutorial-wordpress-28-widget-api/">tutorial</a>.
* Author: Jesse Altman
* Author URI: http://jessealtman.com/
*/
class HelloWorldWidget extends WP_Widget
{
/**
* Declares the HelloWorldWidget class.
*
*/
function HelloWorldWidget(){
$widget_ops = array('classname' => 'widget_hello_world', 'description' => __( "Example widget demoing WordPress 2.8 widget API") );
$control_ops = array('width' => 300, 'height' => 300);
$this->WP_Widget('helloworld', __('Hello World Example'), $widget_ops, $control_ops);
}
In order to get WordPress to recognize this plugin, you need to give
it the proper header. You should include a Plugin Name, Version, Plugin
URI, Description, Author, and Author URI.
The next thing you need to do is declare your class. The class
should be named something similar to what your widget is called. This
class must extend the WP_Widget class in order to function properly. As
with any class, you must give it a declaration.
In the class declaration, you need to have a few variables.$widget_ops
contains the class name and the description of the widget. WordPress’
admin interface will use this to display the correct information for
your widget. I opted to use $control_ops which is an
optional parameter that can be passed to the WP_Widget function that
will specify the width and height of the WordPress admin interface
options menu for your widget. The final function in the class
description is WP_Widget and must always be in the class declaration.
This function creates your widget in the WordPress admin interface.
Following the class declaration you should provide the widget(), update(), and form()
functions to your file. You can then create custom functions used
throughout the class. You should place these functions after the form() function.
Wrapping It Up
In order to finish the widget, you need to register it. Let’s take a look at the end of the Hello World example widget.
}// END class
/**
* Register Hello World widget.
*
* Calls 'widgets_init' action after the Hello World widget has been registered.
*/
function HelloWorldInit() {
register_widget('HelloWorldWidget');
}
add_action('widgets_init', 'HelloWorldInit');
?>
First thing to notice is that this is outside of the
HelloWorldWidget class. You must not include the final function in your
class. The HelloWorldInit() function uses the register_widget()
function provided by WordPress. This function will register the widget
with WordPress and allow users to access it via the WordPress admin
interface. The add_action() function is also WordPress specific. This function will add your HelloWorldInit() function to WordPress’ widget_init() function. This ensures your widget is run when WordPress initiates widgets.
Finished Product
<?php
/*
* Plugin Name: Hello World Example
* Version: 1.0
* Plugin URI: http://jessealtman.com/2009/06/08/tutorial-wordpress-28-widget-api/
* Description: Hello World example widget using the the WordPress 2.8 widget API. This is meant strictly as a means of showing the new API using the <a href="http://jessealtman.com/2009/06/08/tutorial-wordpress-28-widget-api/">tutorial</a>.
* Author: Jesse Altman
* Author URI: http://jessealtman.com/
*/
class HelloWorldWidget extends WP_Widget
{
/**
* Declares the HelloWorldWidget class.
*
*/
function HelloWorldWidget(){
$widget_ops = array('classname' => 'widget_hello_world', 'description' => __( "Example widget demoing WordPress 2.8 widget API") );
$control_ops = array('width' => 300, 'height' => 300);
$this->WP_Widget('helloworld', __('Hello World Example'), $widget_ops, $control_ops);
}
/**
* Displays the Widget
*
*/
function widget($args, $instance){
extract($args);
$title = apply_filters('widget_title', empty($instance['title']) ? ' ' : $instance['title']);
$lineOne = empty($instance['lineOne']) ? 'Hello' : $instance['lineOne'];
$lineTwo = empty($instance['lineTwo']) ? 'World' : $instance['lineTwo'];
# Before the widget
echo $before_widget;
# The title
if ( $title )
echo $before_title . $title . $after_title;
# Make the Hello World Example widget
echo '<div style="text-align:center;padding:10px;">' . $lineOne . '<br />' . $lineTwo . "</div>";
# After the widget
echo $after_widget;
}
/**
* Saves the widgets settings.
*
*/
function update($new_instance, $old_instance){
$instance = $old_instance;
$instance['title'] = strip_tags(stripslashes($new_instance['title']));
$instance['lineOne'] = strip_tags(stripslashes($new_instance['lineOne']));
$instance['lineTwo'] = strip_tags(stripslashes($new_instance['lineTwo']));
return $instance;
}
/**
* Creates the edit form for the widget.
*
*/
function form($instance){
//Defaults
$instance = wp_parse_args( (array) $instance, array('title'=>'', 'lineOne'=>'Hello', 'lineTwo'=>'World') );
$title = htmlspecialchars($instance['title']);
$lineOne = htmlspecialchars($instance['lineOne']);
$lineTwo = htmlspecialchars($instance['lineTwo']);
# Output the options
echo '<p style="text-align:right;"><label for="' . $this->get_field_name('title') . '">' . __('Title:') . ' <input style="width: 250px;" id="' . $this->get_field_id('title') . '" name="' . $this->get_field_name('title') . '" type="text" value="' . $title . '" /></label></p>';
# Text line 1
echo '<p style="text-align:right;"><label for="' . $this->get_field_name('lineOne') . '">' . __('Line 1 text:') . ' <input style="width: 200px;" id="' . $this->get_field_id('lineOne') . '" name="' . $this->get_field_name('lineOne') . '" type="text" value="' . $lineOne . '" /></label></p>';
# Text line 2
echo '<p style="text-align:right;"><label for="' . $this->get_field_name('lineTwo') . '">' . __('Line 2 text:') . ' <input style="width: 200px;" id="' . $this->get_field_id('lineTwo') . '" name="' . $this->get_field_name('lineTwo') . '" type="text" value="' . $lineTwo . '" /></label></p>';
}
}// END class
/**
* Register Hello World widget.
*
* Calls 'widgets_init' action after the Hello World widget has been registered.
*/
function HelloWorldInit() {
register_widget('HelloWorldWidget');
}
add_action('widgets_init', 'HelloWorldInit');
?>
If you combine all of these code snippets together, this is what
your final PHP file should look like. Click the images for a larger
view.
|