Pimp my widget: Object Oriented school

June 12, 2010 by Zoran

In my previous post we looked into equipping or WP blog with widgets to give it a new look and hopefully make it a little more pleasing to the eye. Today we are going to take a step further… hopefully. Since object orientation is the best thing that happened since the wheel (or so I hear ;)) we should try to tap into some of that godly nectar and ambrosia. So, we will be giving our RSS widget introduced in my last post an OO makeover.

How do we do that. First a little disclaimer… If you are trudging with me through the jungles of WP code you need to have a WP installation 2.8 or later because widgets did not have their fancy OO clothes before then… They were clad only in leopard skins and bear furs. Well, let’s see how the WP crew does it (you just gotta love open source :)). Remember that WP comes with its own set of already installed widgets (Categories list, Archives list, Latest posts, …). We can track their implementation to the <wp_install_folder>/wp-includes/default-widgets.php file. After some brain exercise we see that they are all implemented as subclasses of the WP_widget class.

Let’s go on a class hunt. We finally locate it in the nether regions of the <wp_install_folder>/wp-includes/widgets.php file (well, not exactly in the nether regions… it is actually immediately at the beginning of the file staring us in the face, but that would sound totally lame if I wrote it). What can the old WP_Widget tell us. We can see that there are actually 4 important methods we need to be concerned about:

  • __construct – the class constructor where we can initialize the widget – important to us because this is where we set the widget’s name which will be shown in the administration interface
  • widget – method displaying the widget content – important to us because, well, it displays the widget and it is the primary reason for all of this digging :)
  • form – method displaying the widget’s WP administration area content so we can enter some widget options – not important in our case because our widget does not need any options (at least for now)
  • update – method called before the widget options are saved into the database – also not very important right now because we still do not have any options

I will not go into a detailed description of these functions but you can always check their implementation in the base class as well in the default WP widgets and get all the information you wanted and probably some you didn’t (as they say in many IT books “that is left as an exercise to the reader”).

So let’s finally see our OO implementation:

class Trdg_RSS_Widget extends WP_Widget
{
  function __construct()
  {
    parent::__construct(false, $name = 'Tardigrade RSS link');
  }

  function widget($args, $instance)
  {
    extract( $args );
    ?>
    <?php echo $before_widget; ?>
      <a id="rss-icon" href="<?php bloginfo('rss2_url'); ?>">
        <img
          src="<?php bloginfo('template_directory'); ?>/images/RSS_icon.png"
          alt="RSS icon" />
      </a>
    <?php echo $after_widget; ?>
    <?php
  }

  function update($new_instance, $old_instance)
  {
    return $new_instance;
  }

  function form($instance)
  {
    echo '<p class="no-options-widget">' .
      __('There are no options for this widget.') . '</p>';
    return 'noform';
  }
}

register_widget('Trdg_RSS_Widget');

All we needed to was copy the code displaying the widget content from our old widget_tardigrade_rss_link function to the Trdg_RSS_Widget::widget method and call the WP_Widget‘s constructor in our constructor. The form and update methods are just copies from the base class and are included here just for completeness. If your widget has no options to set, like this one here, you can easily leave them out of the class definition.

You also noticed that we register the new and improved widget with the register_widget function instead of the old school register_sidebar_widget one.

And that’s all there is to it. Our widget got its makeover and we can put OO experience in our resumes ;)