Define Your Own WordPress Widgets

Raj Sekharan
Share

Widgets are small pieces of content that can be placed in one of the widgetized regions of your WordPress theme. A widget may contain some simple static content like a newsletter subscription form, introductory text, advertisements or some dynamic content such as a list of recent tweets from your Twitter account.

In this article you will learn:

  1. How to create simple widgets without coding using the Text widget.
  2. How to create dynamic data-driven widgets created through a WordPress plugin.

Static Widgets

Static widgets can be used to place some unchanging text or HTML code in a region. These are very easy to create and they will be sufficient for most content you will need to add to your blog’s sidebars.

Creating Static Widgets

In this example we will create a widget that will show a subscription form to an email newsletter in the sidebar of the blog. Follow the steps below having logged into the WordPress administration panel.

Drag and drop the Text widget to a region in the sidebar as shown in the image below:
Widgets in the WP Dashbaord

Expand the menu and paste the needed text or HTML code:
Adding static widget content

Click on the Save button. The widget with its content will appear in the front end of the website in the sidebar as shown in the image below:
static widget displayed in the sidebar

Dynamic Widgets

In this tutorial we will create a widget for showing a Twitter feed in the sidebar. I will illustrate this example by creating a plugin that adds a new Widget called “Twitter Feed” to the Widgets interface. To accomplish the same with the theme, place the entire code in the functions.php file of your WordPress theme.

Creating A WordPress Plugin

Before starting the definition of the Widget we must first create the plugin that will contain the definition.

Step 1. Create Plugin File

Create a file named tweet_feed.php in the wp-content/plugins/ directory under your WordPress installation directory.

Step 2: Add The Plugin Declaration Comments

<?php

/*
Plugin Name: Twitter Feed Widget
Author: Raj Sekharan
Author URI: http://www.nodesman.com
Description: Add a twitter feed to your sidebar.
*/

Open a PHP code section and then place the comment section. WordPress looks for the above comments in the first few line of a PHP file to identify it as a wordpress plugin file. The information in this comment section will be used to show the plugin in the plugins administration page.

Step 3: Create A Sub Class Of WP_Widget

Create a sub class of the predefined class WP_Widget with a descriptive name. I will use Twitter_Feed_Widget in this case. The sub class should have four methods:

  1. widget()
  2. update()
  3. form()
  4. Twitter_Feed_Widget()   (or whatever the name of your widget class is)

Even if your server is running PHP5 it is necessary to define a function with the same name as the class name.

class Twitter_Feed_Widget extends WP_Widget
{
    function  widget($args,$instance)
    {       

    }

   function Twitter_Feed_Widget()
   {

   }

   function  update($new_instance,$old_instance)
   {

   }

   function form($instance)
   {

   }
}

This forms the framework in which the entire definition of the widget will be placed. In the above set of functions only the Twitter_Feed_Widget() and widget() functions are mandatory.

The Widget Options Panel is Optional

Defining the form() and update() functions is optional. They are necessary only if your widget needs some configuration input from the user. You can leave them out if you don’t want to provide any widget options. In that case the options panel will shown as given in the image below.
widget without options

Step 4:  Define the Options Panel Interface

WordPress expects the form() function defined above to output the input fields to the receive input from the user. In the case of the Twitter Feed widget we will provide the following options:

  1. Title of the Widget
  2. Username of Twitter user
  3. Number of tweets to show.

Below is the definition of the form() function for the Twitter feed widget:

function form($config)
{
?>
    <label for="<?php echo $this->get_field_id("title");  ?>">
    <p>Title: <input type="text"  value="<?php echo $config['title']; ?>" name="<?php  echo $this->get_field_name("title"); ?>" id="<?php  echo $this->get_field_id("title") ?>"></p>
    </label>

    <label for="<?php echo $this->get_field_id("username");  ?>">
    <p>Twitter Username: <input  type="text" value="<?php echo $config['username'];  ?>" name="<?php echo  $this->get_field_name("username"); ?>" id="<?php  echo $this->get_field_id("username") ?>"></p>
    </label>

    <label for="<?php echo  $this->get_field_id("num"); ?>">
    <p>Number Of Tweets: <input  type="text" size="3" value="<?php echo  $config['num']; ?>" name="<?php echo  $this->get_field_name("num"); ?>" id="<?php echo  $this->get_field_id("num") ?>"></p>
    </label>
<?php        
}

The form() Function Explained

  1. The function takes one argument – $config. This variable contains the configuration values for this widget.
  2. The fields in the options are placed within a <form> tag that is submitted via an AJAX request. Which means a form tag shouldn’t be added in the definition above. WordPress handles the saving of the widget data for you.
  3. The $this->get_field_name() and $this->get_field_id() functions are used to generate names for the form fields so that there are no conflicts in names with the input fields on the Widget options page.

Step 5: Save Options Panel Settings

The business logic that saves the settings selected in the options panel above should be placed in the save() function. In the case of our Twitter feed:

function update($newinstance,$oldinstance)
{
    $instance =  $oldinstance;
    //update the username
    $instance['username']=  $newinstance['username'];
    $instance['title'] =  $newinstance['title'];
    $num = (int)$newinstance['num'];
    $num = intval($num);
    $num = ($num>1)?$num:1;
    $instance['url'] = "http://api.twitter.com/1/statuses/user_timeline.json?screen_name={$newinstance['username']}&count={$num}";
    $instance['num'] = $num;
    return $instance;
}

The update() Function Explained

  • The function takes two arguments :
  1. The first argument – $newinstances in this case – has the configuration information of the widget as it was entered in the options panel. WordPress automatically detects all the form elements and uses their names for array elements.
  2. The second argument – $oldinstance in this case – has the configuration information of the Widget prior to changing the settings.
  • Line 4 of the function updates the title of the widget.
  • Line 8 of the function updates the URL of the Twitter API user timline JSON feed.
  • Lines 9 saves the number of tweets to show ensuring that the value is an integer and positive.
  • Options Panel Doesn’t Support File Uploads

    You cannot add a file field in the options panel of a widget. If your configurable widget takes file inputs from the user then you must create a separate administration screen for the widget’s options and add a URL field in the widget configuration form.

    Step 6: Define the Widget

    Now we are going to define the widget itself. WordPress expects the HTML of the widget to be generated by a function named widget(). Shown below is the definition of the Twitter Widget:

    function widget($args,$instance)
    {
         extract($args,EXTR_SKIP);
         if (empty($instance['url']) || empty($instance['username']))
        	  return;
         $title =  ($instance['title'])?$instance['title']:"Latest Tweets";
    
         $tweets =  $this->get_tweets($instance['url'],$instance['username'],$instance['num']);
         $max = $instance['num'];
         echo $before_widget;
    ?>
    <div class="twitter-feed-widget">
    <php echo $before_title; ?>
    <strong><?php echo $title; ?></strong>
    <php echo $after_title; ?>
    <?php
    $count=0;
    foreach ($tweets as $tweet)
    {
        $text = $tweet['tweet'];
    ?>
    <div class="tfw-tweet"><a href="<?php echo $tweet['url'] ?>"><?php echo $text;  ?></a></div><br/>
    <?php
        $count++;
        if ($count == $num)
         break;
    }
    ?>
    </div>
    <?php
    echo $after_widget;
    }

    The widget() Function Explained

    The widget function takes two parameters: $args and $instance.

    1. The $args variable contains a few theme relaetd variables:
    1. before_widget – The HTML to be printed before the widget body.
    2. >after_widget – The HTML to be printed after the widget body.
    3. before_title – The HTML to be printed before the title of the widget.
    4. after_title – The HTML to be printed after the title fo the widget.
    • The above mentioned variables are set in the WordPress theme by the Theme author in the declaration of the theme sidebar in the functions.php file.
    • The variable $instance has the configuration information for this widget instance that was saved in the update() function in the previous step.
    • The get_tweets() function above will fetch tweets of the twitter user passed in the variable $username. The tweets are returned as an associative array. The implementation of the function is as below:
        function get_tweets($feed_url,$username, $num=10)
         {
             //check if the feed is in the list of feeds
             $feeds = get_option("_tfw_feeds");
             $hash = md5($feed_url);
             $tweets = array();
             if (isset($feeds[$hash]))
             {
                 $timeOfLastFetch = intval(@$feeds[$hash]["last_update"]);
                 if ($timeOfLastFetch-time() >300) //update the tweets every 5 minutes
                 {
                      $whetherUpdateTweets = true;
                 }
                 else
                 {
                       if (is_array($feeds[$hash]['tweets']) && count($feeds[$hash]['tweets'] >= $num))
                       {
                          return $feeds[$hash]['tweets'];
                       }
                       else
                       {
                            $whetherUpdateTweets=true;
                       }
                 }
             }
             else
                 $whetherUpdateTweets = true;      
      
             if ($whetherUpdateTweets)
             {
      	       if ($tweetsList = file_get_contents($feed_url))
      	       {
      		   $tweetsList = json_decode($tweetsList);
      		   foreach ($tweetsList as $tweet)
      		   {
      		       $tweets[] = array("tweet"=>$tweet->text,"url"=>"https://twitter.com/#!/{$username}/status/{$tweet->id_str}");
      		   }
      	       }
      	       $hash = md5($feed_url);
      	       $feeds = get_option("_tfw_feeds");
      	       $feeds[$hash] = array("last_update"=>time(),"tweets"=>$tweets);
      	       update_option("_tfw_feeds",$feeds);
             }
             return $tweets;
      
         }
    • The first line of the calls the extract() function. The function takes an associative array. It creates variables named after the keys of the array and sets them to the value corresponding to those keys.
    • The second line ensures that the widget is not shown at all if the user doesn’t save their username.
    • The fourth line ensures that the $title variable is always set to a usable string.
    • The next four lines print the content of the above mentioned theme related variables.
    • The get_tweets() function retrieves a list of tweets of the twitter user. The RSS filename that was saved in the update step is passed to this function as a parameter. It returns an array of associative arrays each of which have the tweet text and the URL to the tweet as elements.
    • The foreach loop prints the tweets.

    Step 7: Define The Widget Class Constructor

    The widget class’s constructor gives WordPress some information on the widget. The name of the widget, the dimensions of the widget’s options panel, the description to be shown under the widget’s name in the Widgets administration page are all configured in this function. This constructor defines two arrays and then passes them to the WP_Widget parent class.

    function Twitter_Feed_Widget()
    {
       $widget_options = array(
          'classname'=>'widget-tweet',
          'description'=>__('This widget shows the twitter feed for the selected user.')
       );
       $control_options = array(
          'height'=>300,
          'width' =>300
       );
       $this->WP_Widget('twitter_feed_widget','Twitter Feed Widget',$widget_options,$control_options);
    }

    The Constructor Explained

    1. The first argument to the parent class constructor is a unique identified for the widget defined by this class. The widget’s content will be enclosed in a <div> element. This element’s class attribute will be set to this value.
    2. The second argument is the name of the widget as it will be shown to the user in the Widgets administration page.
    3. The third argument is an associative array with the following keys:
      1. classname – The entire widget along with the title will be placed within a <li> element. This element’s class name will be set to this value.
      2. description – The description of the widget as it will be shown in the Widgets Administration section.
    4. The fourth argument is an associative array with the following keys:
      1. height – Height of the widget’s options panel.
      2. width – Width of the widget’s options panel.

    Step 8: Register the Widget with WordPress

    Having defined the Widget class we have to get WordPress to treat this class as a widget definition.

    First, we add a function that attaches to the widget_init hook:

    add_action("widgets_init","myplugin_widget_init");

    WordPress expects all plugins and themes that want to register widgets to hook onto the widgets_init hook. The above line of code registers the myplugin_widget_init() function with the widgets_init hook. We then register the widget in the function body:

    function myplugin_widget_init()
    {
        register_widget("Twitter_Feed_Widget");
    }

    The register_widget() function takes one argument – the name of the widget class.

    Important Notes on WordPress Widgets

    WordPress Widget API Was Changed

    Prior to version 2.8, WordPress used a different method of defining widgets. Instead of defining a widget class you had to pass the function names as callbacks to two functions – register_widget_control() and register_sidebar_widget().

    These functions are deprecated and will be removed in future versions. Do not use this method to create widgets. However, you will encounter these functions in the source code of existing popular plugins.

    Cache Widget Output

    Some dynamic widgets consume much bandwidth, CPU and/or other resources to display its content. For example, the Twitter Feed widget relies on the user’s Tweet RSS feed provided by Twitter. Downloading the feed every single time the widget is shown will overload Twitter’s server. This will result in the tweet feed loading unreliably.

    Instead if the feed was updated only once every 5 or 10 minutes the Twitter feed will always be available. This will avoid throttling of your WordPress blog’s web server by Twitter’s. The Twitter Feed Widget plugin in the example above has been implemented such that the feeds are fetched only once every 5 minutes.

    Add Enclosing Markup and Identifiers

    Widgets generated by plugins will be placed in the regions of many different themes. Insanely useful though your widget may be, it will be a blot on the face of a website if it stands out looking out of place.

    Enclosing all of the elements that your widget shows in a <div> or <span> element and providing them appropriate class and id attributes can help themers to customize the look and feel of your widget to suit the visual background in which it is placed.

    Widgets Make Users’ Lives Easier

    WordPress is the world’s most popular blogging platform because of the ease of use. Prior to implementation of widgets, users had to open up the theme files and then insert code at the appropriate location to add new features to the sidebar. That was fine when most bloggers were very tech-savvy.

    Whether you are creating plugins for a client or for public release, the Widgets are a way to put control in the hands of bloggers who may not be as technically proficient as you and make the experience of using your software a lot better. Widgets help users get the most out of your plugin without risky and daunting edits to their WordPress theme.