WordPress 3: Building a Widget

0
77
10 min read

 

WordPress 3 Plugin Development Essentials

WordPress 3 Plugin Development Essentials

Create your own powerful, interactive plugins to extend and add features to your WordPress site

        Read more about this book      

(For more resources on WordPress, see here.)

The plan

What exactly do we want this plugin to do? Our widget will display a random bit of text from the database. This type of plugin is frequently used for advertisement rotations or in situations where you want to spruce up a page by rotating content on a periodic basis. Each instance of our plugin will also have a “shelf life” that will determine how frequently its content should be randomized.

Let’s take a moment to come up with some specifications for this plugin. We want it to do the following:

  • Store multiple chunks of content, such as bits of Google Adsense code
  • Be able to randomly return one of the chunks
  • Set a time limit that defines the “shelf life” of each chunk, after which the “random” chunk will be updated

Widget overview

Even if you are already familiar with widgets, take a moment to look at how they work in the WordPress manager under Appearance | Widgets. You know that they display content on the frontend of your site, usually in a sidebar, and they also have text and control forms that are displayed only when you view them inside the manager. If you put on your thinking cap, this should suggest to you at least two actions: an action that displays the content on the frontend, and an action that displays the form used to update the widget settings inside the manager. There are actually a total of four actions that determine the behavior of a standard widget, and you can think of these functions as a unit because they all live together in a single widget object. In layman’s terms, there are four things that any widget can do. In programmatic terms, the WP_Widget object class has four functions that you may implement:

  • The constructor: The constructor is the only function that you must implement. When you “construct” your widget, you give it a name, a description, and you define what options it has. Its name is often __ construct(), but PHP still accepts the PHP 4 method of naming your constructor function using the name of the class.
  • widget(): It displays content to users on the frontend.
  • form(): It displays content to manager users on the backend, usually to allow them to update the widget settings.
  • update(): It prepares the updated widget settings for database storage. Override this function if you require special form validation.

In order to make your widget actually work, you will need to tell WordPress about it by registering it using the WordPress register_widget() function. If you want to get a bit more information about the process, have a look at WordPress’ documentation here.

Let’s outline this in code so you can see how it works.

Preparation

As always, we’re going to go through the same setup steps to get our plugin outlined so we can get it activated and tested as soon as possible.

  1. Create a folder inside the wp-content/plugins/ directory. We are naming this plugin “Content Rotator”, so create a new folder inside wp-content/ plugins/ named content-rotator.
  2. Create the index.php file.
  3. Add the Information Head to the index.php file. If you forgot the format, just copy and modify it from the Hello Dolly plugin like we did in the previous article, Anatomy of a WordPress Plugin.
    We’re giving you bigger sections of code than before because hopefully by now you’re more comfortable adding and testing them. Here is what our index.php looks like:

    <?php
    /*--------------------------------------------------------------
    ----------------
    Plugin Name: Content Rotator
    Plugin URI: http://www.tipsfor.us/
    Description: Sample plugin for rotating chunks of custom content.
    Author: Everett Griffiths
    Version: 0.1
    Author URI: http://www.tipsfor.us/
    ----------------------------------------------------------------
    --------------*/
    // include() or require() any necessary files here...
    include_once('includes/ContentRotatorWidget.php');
    // Tie into WordPress Hooks and any functions that should run on
    load.
    add_action('widgets_init', 'ContentRotatorWidget::register_this_
    widget');
    /* EOF */

  4. Add the folders for includes and tpls to help keep our files organized.
  5. Add a new class file to the includes directory. The file should be named ContentRotatorWidget.php so it matches the include statement in the index.php file. This is a subclass which extends the parent WP_Widget class. We will name this class ContentRotatorWidget, and it should be declared using the extends keyword.

    <?php
    /**
    * ContentRotatorWidget extends WP_Widget
    *
    * This implements a WordPress widget designed to randomize chunks
    of content.
    */
    class ContentRotatorWidget extends WP_Widget
    {
    public $name = 'Content Rotator';
    public $description = 'Rotates chunks of content on a
    periodic basis';
    /* List all controllable options here along with a
    default value.
    The values can be distinct for each instance of the
    widget. */
    public $control_options = array();

    //!!! Magic Functions
    // The constructor.
    function __construct()
    {
    $widget_options = array(
    'classname' => __CLASS__,
    'description' => $this->widget_desc,
    );
    parent::__construct( __CLASS__, $this->name,$widget_
    options,$this->control_options);
    }
    //!!! Static Functions
    static function register_this_widget()
    {
    register_widget(__CLASS__);
    }
    }
    /* EOF */

This is the simplest possible widget—we constructed it using only the __ construct() function. We haven’t implemented any other functions, but we are supplying enough information here for it to work. Specifically, we are supplying a name and a description, and that’s enough to get started. Let’s take a moment to explain everything that just happened, especially since the official documentation here is a bit lacking.

When we declared the ContentRotatorWidget class, we used the extends keyword. That’s what makes this PHP class a widget, and that’s what makes object-oriented code so useful.

The __construct() function is called when an object is first created using the new command, so you might expect to see something like the following in our index. php file:

<?php
$my_widget = new ContentRotatorWidget();
?>

However, WordPress has obscured that from us—we just have to tell WordPress the classname of the widget we want to register via the register_widget() function, and it takes care of rest by creating a new instance of this ContentRotatorWidget. There is a new instance being created, we just don’t see it directly. Some of the official documentation still uses PHP 4 style examples of the constructor function— that is to say that the function whose name shares the name of the class. We feel that naming the constructor function __construct is clearer.

You may have wondered why we didn’t simply put the following into our index.php file:

register_widget('ContentRotatorWidget'); // may throw errors
if called too soon!

If you do that, WordPress will try to register the widget before it’s ready, and you’ll get a fatal error:

“Call to a member function register() on a non-object”.

That’s why we delay the execution of that function by hooking it to the widgets_ init action.

We are also tying into the construct of the parent class via the parent::__ construct() function call. We’ll explain the hierarchy in more detail later, but “parent” is a special keyword that can be used by a child class in order to call functions in the parent class. In this case, we want to tie into the WP_Widget __ construct() function in order to properly instantiate our widget.

Note our use of the PHP __CLASS__ constant—its value is the class name, so in this case, we could replace it with ContentRotatorWidget, but we wanted to provide you with more reusable code. You’re welcome.

Lastly, have a look at the class variables we have declared at the top of the class: $name, $description, and $control_options. We have put them at the top of the class for easy access, then we have referenced them in the __construct() function using the $this variable. Note the syntax here for using class variables. We are declaring these variables as class variables for purposes of scope: we want their values to be available throughout the class.

Please save your work before continuing.

Activating your plugin

Before we can actually use our widget and see what it looks like, we first have to activate our plugin in the manager. Your widget will never show up in the widget administration area if the plugin is not active! Just to be clear, you will have to activate two things: your plugin, and then your widget.

The code is simple enough at this point for you to be able to quickly track down any errors.

Activating the widget

Now that the plugin code is active, we should see our widget show up in the widget administration area: Appearance | Widgets.

Take a moment to notice the correlation between the widget’s name and description and how we used the corresponding variables in our constructor function. Drag your widget into the primary widget area to make it active.

Once it has been activated, refresh your homepage. Your active widget should print some text in the sidebar.

(Move the mouse over the image to enlarge it.)

Congratulations! You have created your first WordPress widget! It is printing a default message: function WP_Widget::widget() must be over-ridden in a sub-class, which is not very exciting, but technically speaking you have a functional widget. We still need to enable our widget to store some custom options, but first we should ensure that everything is working correctly.

Having problems?

No widget? If you have activated your plugin, but you do not see your widget showing up in the widget administration area, make sure you have tied into a valid WordPress action! If you misspell the action, it will not get called! The action we are using in our index.php is widgets_init—don’t forget the “s”!

White screen? Even if you have PHP error-reporting enabled, sometimes you suddenly end up with a completely white screen in both the frontend and in the manager. If there is a legitimate syntax error, that displays just fine, but if your PHP code is syntactically correct, you end up with nothing but a blank page. What’s going on?

A heavy-handed solution for when plugins go bad is to temporarily remove your plugin’s folder from /wp-content/plugins, then refresh the manager. WordPress is smart enough to deactivate any plugin that it cannot find, so it can recover from this type of surgery.

If you are experiencing the “White Screen of Death”, it usually means that something is tragically wrong with your code, and it can take a while to track it down because each time you deactivate the plugin by removing the folder, you have to reactivate it by moving the folder back and reactivating the plugin in the WordPress manager.

This unenviable situation can occur if you accidentally chose a function name that was already in use (for example, register()—don’t use that as a function name). You have to be especially careful of this when you are extending a class because you may inadvertently override a vital function when you meant to create a new one. If you think you may have done this, drop and do 20 push-ups and then have a look at the original parent WP_Widget class and its functions in wp-includes/widgets.php. Remember that whenever you extend a class, it behooves you to look at the parent class’ functions and their inputs and outputs. If this sounds like Greek to you, then the next section is for you.

LEAVE A REPLY

Please enter your comment!
Please enter your name here