There's nothing more boring than a blog that looks just like one of the millions of other blogs floating around the web. Fortunately for WordPress users, plugins and widgets make adding custom functionality to your blog easy. Think of plugins as components where you put your functionality and widgets as components of your user interface. Building your own WordPress plugins and widgets will make your blog truly original, and all you need is basic PHP and HTML knowledge—and your imagination.
In this tutorial, you'll build a simple plugin and widget combo application called BoobTube. BoobTube simply uses a widget to display the newest YouTube video from your blog's YouTube channel. Download the source code to follow along with the instructions.

Building the WordPress Plugin

The first step in building a WordPress plugin is to pick a unique name. In this case, you're going to call it BoobTube, but when you build your own plugin, make sure you choose a name that is not already taken. A duplicate name will cause problems in the WordPress plugin manager, even if you don't distribute your plugin publicly.
Create a directory in wp-content/plugins called boobtube, and create a file called boobtube.php in it. Boobtube.php will be your main plugin file where all your PHP code resides.
Listing 1 shows the entire boobtube.php file. All plugins should include two header components, one for standard plugin information and the other for licensing terms. Even if you don't intend to distribute your plugin, completing the information for these components is good WordPress style.

Walking Through the Plugin Code

First, you have to define a few constants. The first constant is setting up a nonce key.
define('BOOBTUBE_ADMIN_NONCE', 'boobtube-adminpanel-0122');
A nonce is a number used once. It's used to verify that the data submitted via the administrator plugin panel actually comes from the administrator panel rather than from a hacker trying to mess with your plugin.
Next, you set up a few defaults for the BoobTube plugin and widget.
define('BOOBTUBE_HEIGHT', '151');
define('BOOBTUBE_WIDTH', '250');
define('BOOBTUBE_YOUTUBEID', 'Pn-G_pYJJfU');
define('BOOBTUBE_UPDATE_INTERVAL', '10');
define('BOOBTUBE_USERNAME', 'goodganews');
It's always a good idea to verify that your class doesn't already exist before you define it. This prevents naming collisions with other plugins.
if (!class_exists("BoobTube")) {
    class BoobTube {
    ...
    }
}
After you've setup your class and methods, instantiate the class. Again, just to be safe and to avoid a fatal error, make sure the class exists before instantiating it.
if (class_exists("BoobTube")) {
    $boobtube = new BoobTube();
}

Registering the Necessary WordPress Actions

The WordPress documentation says: "actions are triggered by specific events that take place in WordPress, such as publishing a post, changing themes, or displaying a page of the admin panel. Your plugin can respond to the event by executing a PHP function."
To make the BoobTube plugin work, you need to tell WordPress how to run it.
add_action('boobtube/boobtube.php', array(&$boobtube, 'init'));
This tells WordPress to activate boobtube.php, passes it a reference to the $boobtube class you instantiated earlier, and it tells WordPress which method to call. In this case, you tell WordPress to call init, but when you build your own plugin you can call whatever method is appropriate for your implementation.
BoobTube has an administrator panel, so you need to register that action too.
add_action('admin_menu', 'BoobTube_AdminPanel'); 
BoobTube_AdminPanel is simply a function that calls the built-in WordPress function add_options_page described in the WordPress documentation as:
add_options_page(page_title, menu_title, capability, handle, [function]); if (!function_exists('BoobTube_AdminPanel')) { function BoobTube_AdminPanel() { if (!$GLOBALS['boobtube']) { return; } if (function_exists('add_options_page')) { add_options_page('BoobTube Admin Panel', 'BoobTube', 9, basename(__FILE__), array(&$GLOBALS['boobtube'], 'printAdminPanel')); } } }
The last action to register is the widget. Not all plugins require a widget, but BoobTube does. To register a widget, you register a widgets_init action.
add_action('widgets_init', 'BoobTube_Widget');
To learn more about WordPress actions, see the Plugin API documentation.

Building the WordPress Widget

The BoobTube plugin needs a widget to show the YouTube video on your blog. Most widgets have two components:
To build a WordPress widget, you simply extend the built-in WP_Widget class, set up a constructor, and override three methods: widget, form and update. In this example, the widget code is stored in a widget.php file located in the wp-content/plugins/boobtube directory and included in the boobtube.php main plugin file.
Here's all of the widget code.
<?php class BoobTube_Widget extends WP_Widget { function BoobTube_Widget() { $widget_ops = array('classname' => 'boobtube', 'description' => 'My Video'); $control_ops = array('width' => '300', 'height' => '350', 'id_base' => 'boobtube-widget'); $this->WP_Widget('boobtube-widget', 'Boob Tube', $widget_ops, $control_ops); } function widget($args, $instance) { extract($args); $title = apply_filters('widget_title', $instance['title'] ); // Controlled by theme. echo $before_widget; if ($title) { echo $before_title . $title . $after_title; } $bt =& $GLOBALS['boobtube']; $bt->watch(); // Controlled by theme. echo $after_widget; } function update($new_instance, $old_instance) { $instance = $old_instance; $instance['title'] = strip_tags($new_instance['title']); return $instance; } function form($instance) { $defaults = array( 'title' => 'My Video'); $instance = wp_parse_args((array) $instance, $defaults); $title = htmlspecialchars($instance['title']); echo "<p>\n<label for=\"" . $this->get_field_name('title') . "\">Title:</label>\n"; echo "\n<input type=\"text\" id=\"" . $this->get_field_id('title') . "\" name=\"" . $this->get_field_name('title') . "\" value=\"" . $title . "\" style=\"width:100%\" />\n</p>\n"; } } ?>
The constructor sets up the default values and calls the parent WP_Widget constructor.
class BoobTube_Widget extends WP_Widget { function BoobTube_Widget() { $widget_ops = array('classname' => 'boobtube', 'description' => 'My Video'); $control_ops = array('width' => '300', 'height' => '350', 'id_base' => 'boobtube-widget'); $this->WP_Widget('boobtube-widget', 'Boob Tube', $widget_ops, $control_ops); }
The widget method displays the widget on your blog. You must use the $before_widget, $after_widget, $before_title and $after_title variables because these are controlled by the theme.
   function widget($args, $instance) {
       extract($args);
       $title = apply_filters('widget_title', $instance['title'] );
       // Controlled by theme.
       echo $before_widget;
       if ($title) {
      echo $before_title . $title . $after_title;
       }
       $bt =& $GLOBALS['boobtube'];
       $bt->watch();
       // Controlled by theme.
       echo $after_widget;
   }
The form method is where you configure the HTML BoobTube widget. The widget form posts to the update method described next. Your plugin can be used in multiple widgets, each with customizable features. For BoobTube, you're updating only the widget title.
function form($instance) { $defaults = array( 'title' => 'My Video'); $instance = wp_parse_args((array) $instance, $defaults); $title = htmlspecialchars($instance['title']); echo "<p>\n<label for=\"" . $this->get_field_name('title') . "\">Title:</label>\n"; echo "\n<input type=\"text\" id=\"" . $this->get_field_id('title') . "\" name=\"" . $this->get_field_name('title') . "\" value=\"" . $title . "\" style=\"width:100%\" />\n</p>\n"; }
The update method takes the form method data and updates BoobTube's widget title.
    function update($new_instance, $old_instance) {
       $instance = $old_instance;
       $instance['title'] = strip_tags($new_instance['title']);
       return $instance;
   }
That's it. As you can see, customizing WordPress is quite easy. Download the source code for BoobTubeand hack away at it. Then build your own plugin or customize an existing WordPress plugin if it doesn't do everything you want it to do.
Code Download
About the Author
Keith Vance is a software engineer and a journalist. He's been developing web applications professionally since 1997, and he received his journalism degree from the University of Washington in 2008. to e-mail him.