Widgets are a neat way of giving site owners some control over the look (and sometimes functionality) of their WordPress sites. In this series, we are going to be creating a handful of WordPress widgets by combining the Widgets API with other external APIs.
The series will consist of the following tutorials:
- An Introduction
- Related Posts Widget
- Login Widget
- FAQ Widget
- Most Popular Posts Widget with Google Analytics Integration
- Physical Address Widget with Google Maps Integration
- Conclusion
In this tutorial, I will introduce you to the WordPress Widgets API by (re)creating a simple text widget. We will dissect and examine the different functions that make up the widget so as to understand how WordPress widgets work in general.
This widget will also serve as a basis on which we will build on when creating other widgets in the subsequent parts of this series.
WordPress Widgets
WordPress widgets add content and features to your sidebars or widgetized areas of your theme. Widgets are designed to provide a simple and easy-to-use way of giving design and structural control of the WordPress theme to the user without requiring them to know how to code.
Most WordPress widgets offer customization and options such as forms to fill out, optional images and other customization features.
Examining The Widget Class
The easiest way to create a WordPress widget is to inherit the
WP_Widget
class. This way you can use the built-in functions to update
the widget, display the widget, and create an admin interface for the
widget.
To fully understand how widgets work, we will create and examine an empty widget. We will then define each function that makes up the widget so see how they work together to create a working widget.
Our Widget Definition
<?php class TutsPlusText_Widget extends WP_Widget { // widget constructor public function __construct(){ } public function widget( $args, $instance ) { // outputs the content of the widget } public function form( $instance ) { // creates the back-end form } // Updating widget replacing old instances with new public function update( $new_instance, $old_instance ) { // processes widget options on save } }
The Functions in Detail
Let's look at each function in more detail:
__construct()
This function registers the widget with WordPress
widget()
This function is responsible for the front-end display of the widget. It outputs the content of the widget
update()
Processes the widget options on save. Use this function to update your widget (option). This function takes two parameters:
-
$new_instance
– Values just sent to be saved. These values will be coming from the form defined within the form() method -
$old_instance
– Previously saved values from the database
Be sure to sanitize all user submitted values here. User-submitted values must always be sanitized before being sent to the database
form()
The form()
method/function is used to define the back-end widget form
– which you see in the widgets panel in the dashboard This form
enables a user to set up the title and other options for the widget.
This function takes the following parameter(s):
-
$instance
– Previously saved values from the database
Creating Our Widget
To create our widget, we will follow the following steps:
- Define what we are creating
- Register our widget with WordPress
- Build the back-end form
- Save values to the database
- Define the front-end Display
- Register the widget
What Are We Creating?
As we mentioned earlier, we are creating a simple text widget that enables a user to enter a title and some arbitrary text that will then be output in the front-end of their website where the widget is placed.
Widget Constructor
The constructor enables us to initialize our widget by overwriting the parent class (standard WP_Widget
class).
<?php public function __construct(){ parent::__construct( 'tutsplustext_widget', __( 'TutsPlus Text Widget', 'tutsplustextdomain' ), array( 'classname' => 'tutsplustext_widget', 'description' => __( 'A basic text widget to demo the Tutsplus series on creating your own widgets.', 'tutsplustextdomain' ) ) ); load_plugin_textdomain( 'tutsplustextdomain', false, basename( dirname( __FILE__ ) ) . '/languages' ); }
In the code above, we call the parent WP_Widget class's construct function and pass it the foolowing arguments:
- Base ID - A unique identifier for the widget. Must be in lower case. If left empty a portion of the widget's class name will be used.
- Name - This is the name for the widget displayed on the configuration page (in the dashborad).
- And an (optional) array containing a classname and a description. The description is shown on the configuration page (in the WordPress dashboard).
Building the Back-end Form
The back-end form will consist of two fields – a title field and a textarea field. Here is a screenshot of the form as it will look in the Widgets panel:
To generate the above form, we would start with pure HTML and then replace some attribute values with some PHP variables and expressions. The following is the HTML code to create the two fields:
<p> <label for="title">Title</label> <input class="widefat" id="title" name="title" type="text" value="WIDGET TITLE" /> </p> <p> <label for="message">Simple Message</label> <textarea class="widefat" rows="16" cols="20" id="message" name="message">message...</textarea> </p>
To move from this to our final code for the form() function, we will need to make some of the attributes above dynamic – namely, name, id and the label’s for attribute (which has to match the id of the HTML that the label is for). We will also replace the value of the text field and the content of the textarea field with dynamic values from the database if they have been saved already.
Here is the code we end up with:
<?php /** * Back-end widget form. * * @see WP_Widget::form() * * @param array $instance Previously saved values from database. */ public function form( $instance ) { $title = esc_attr( $instance['title'] ); $message = esc_attr( $instance['message'] ); ?> <p> <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <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; ?>" /> </p> <p> <label for="<?php echo $this->get_field_id('message'); ?>"><?php _e('Simple Message'); ?></label> <textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('message'); ?>" name="<?php echo $this->get_field_name('message'); ?>"><?php echo $message; ?></textarea> </p> <?php }
The code above accesses and assigns previously saved values from the
database to two variables – $title
and $message
. We then use the esc_attr()
to encode the returned values and to avoid breaking our code. We then
echo the $title attribute into the value attribute of the text field and
echo $message as the content of the textarea field.
In the code above, you will notice two methods that are probably new to you – get_field_id() and get_field_name().
- get_field_id() – Takes field name as an argument and constructs id attributes for use in form() fields. It ensures that the returned field id is unique
- get_field_name() – Takes field name as an argument and constructs name attributes for use in form() fields. It ensures that the returned field name is unique.
The label tags’ for
attribute is coded to echo out the id value of the elements they label.
The widefat
class is used to ensure that your widget’s fields have the same look as other fields throughout the WordPress dashboard.
Updating Our Widget (Options)
To update our widget, we will write appropriate code in the update method. Here is our code:
<?php /** * Sanitize widget form values as they are saved. * * @see WP_Widget::update() * * @param array $new_instance Values just sent to be saved. * @param array $old_instance Previously saved values from database. * * @return array Updated safe values to be saved. */ public function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); $instance['message'] = strip_tags( $new_instance['message'] ); return $instance; }
The above function takes two parameters – $new_instance
and $old_instance
- $new_instance is an array containing the new settings (of this instance of the widget) that have just been entered by the user via the backend form which we define in the form() function.
- $old_settings is an array containing old settings. These are the values that are currently stored in the database.
The update() function returns an array of settings to save or false to cancel saving.
In the above code, we assign $old_instance to the $instance variable and replace its title and message keys with values from $new_instance. By returning the new and updated array, we effectively update our widget settings.
The strip_tags()
function removes HTML and PHP tags from
a string that’s passed to it. We include this function to avoid a
situation where the users of your theme fail to close tags entered via
the back-end form, resulting in your site breaking (not rendering
properly).
Defining The Front-End
The widget()
function is responsible for the fron-end display of the widget. It takes two parameters – $args
and $instance
.
$args
is an array passed to the register_sidebar() function when
defining the sidebar/widgetised area in which the widget is placed. This
is found in your functions.php
file. Below is an example of a
register_sidebar()
declaration:
The array contains definitions of the opening and closing tags for the widget itself and for the widget’s title.
$instance
is an array containing the settings for the particular instance of the widget. These settings will have been retrieved from the database.
We make use of the tags mentioned above in the final widget code below:
<?php /** * Front-end display of widget. * * @see WP_Widget::widget() * * @param array $args Widget arguments. * @param array $instance Saved values from database. */ public function widget( $args, $instance ) { extract( $args ); $title = apply_filters( 'widget_title', $instance['title'] ); $message = $instance['message']; echo $before_widget; if ( $title ) { echo $before_title . $title . $after_title; } echo $message; echo $after_widget; }
In the above code, we finally get to code the front-end of our
widget. Our widget simply outputs a title and some arbitrary message
(text). The code does exactly that and wraps the widget itself and the
widget’s title inside opening and closing tags defined in functions.php
for the specific widget area (sidebar) where the widget is placed.
We introduce the extract()
function which some may not
be familiar with. This function takes an associative array and returns
its keys as variables. It enables us to echo out $before_widget instead
of $args['before_widget'], thus simplifying our code a little.
The final output on an actual website will look like something like this:
Registering the Widget
The widget has to be registered with WordPress after it is defined so that it becomes available in the widget panel of our WordPress dashboard.
<?php add_action( 'widgets_init', function() { register_widget( 'TutsplusText_Widget' ); });
The Final Code
To keep things simple for the end users of our widgets, we are going to wrap our widget code in a WordPress plugin so that it is easy to install.
This will also enable us to keep all the code we will be creating throughout the series in a single file.
Here is the final code:
<?php /* Plugin Name: Tutsplus Widget Pack Plugin URI: http://code.tutsplus.com Description: A plugin containing various widgets created in a TutsPlus series on WordPress widgets Version: 0.1 Author: Tutsplus Author URI: http://code.tutsplus.com Text Domain: tutsplustextdomain License: GPLv2 Copyright 2014 Tutsplus This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class TutsplusText_Widget extends WP_Widget { public function __construct() { parent::__construct( 'tutsplustext_widget', __( 'TutsPlus Text Widget', 'tutsplustextdomain' ), array( 'classname' => 'tutsplustext_widget', 'description' => __( 'A basic text widget to demo the Tutsplus series on creating your own widgets.', 'tutsplustextdomain' ) ) ); load_plugin_textdomain( 'tutsplustextdomain', false, basename( dirname( __FILE__ ) ) . '/languages' ); } /** * Front-end display of widget. * * @see WP_Widget::widget() * * @param array $args Widget arguments. * @param array $instance Saved values from database. */ public function widget( $args, $instance ) { extract( $args ); $title = apply_filters( 'widget_title', $instance['title'] ); $message = $instance['message']; echo $before_widget; if ( $title ) { echo $before_title . $title . $after_title; } echo $message; echo $after_widget; } /** * Sanitize widget form values as they are saved. * * @see WP_Widget::update() * * @param array $new_instance Values just sent to be saved. * @param array $old_instance Previously saved values from database. * * @return array Updated safe values to be saved. */ public function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); $instance['message'] = strip_tags( $new_instance['message'] ); return $instance; } /** * Back-end widget form. * * @see WP_Widget::form() * * @param array $instance Previously saved values from database. */ public function form( $instance ) { $title = esc_attr( $instance['title'] ); $message = esc_attr( $instance['message'] ); ?> <p> <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <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; ?>" /> </p> <p> <label for="<?php echo $this->get_field_id('message'); ?>"><?php _e('Simple Message'); ?></label> <textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('message'); ?>" name="<?php echo $this->get_field_name('message'); ?>"><?php echo $message; ?></textarea> </p> <?php } } /* Register the widget */ add_action( 'widgets_init', function(){ register_widget( 'TutsplusText_Widget' ); });
Conclusion
In this tutorial, we introduced the series – Creating Your Own WordPress Widgets Using Various APIs. We took a deeper look at what they are, how they work and how to create one.
The purpose of this tutorial was to provide a thorough introduction to the Widgets API and to provide a base widget from which the other widgets in this series can be created.
In the next part of the series, we are going to create a related posts widget. In the meantime, please feel free to leave any questions or comments in the form below.
Comments