Turning a WordPress Sidebar Plugin Into a Widget
Converting a WordPress plugin to a widget doesn’t have to be difficult, but because the official API’s over at wordpress.org are so lacking in detail (the example they provide won’t even work if you cut and paste), many developers can become frustrated with the process.
STEP 1: Using a widget to call a plugin function (no user input)
To begin, assume you have a very simple sidebar plugin that can be called by editing the sidebar theme directly. In your plugin file, there is some function called “nifty_stuff” that outputs some sort of html code to display in the sidebar. In the bad old days of WordPress, the only way a user could display such a plugin would be to edit their theme and add the line of code provided by the plugin author to some point in their sidebar.php file (or whatever the sidebar’s name happens to be). And in older wordpress versions and themes this is still what a blogger needs to do, so you want to leave your user with that option.
If the plugin function requires no input from the user, then the following code will add it to their widgets menu where they can simply drag and drop it into a simplified representation of their sidebar. Just add this code to the same script that holds the “nifty_stuff” function:
function widget_nifty_stuff_init() {
if(!function_exists(‘register_sidebar_widget’)) { return; }
function widget_nifty_stuff($args) {extract($args);
echo $before_widget . $before_title . $after_title;
nifty_stuff();
echo $after_widget;}
register_sidebar_widget(‘Nifty Stuff’,’widget_nifty_stuff’);}
add_action(‘plugins_loaded’, ‘widget_nifty_stuff_init’);
Going through the code, what’s happening is that we first want to create a wrapper for our widget function.
Without that wrapper, php will attempt to use the function “register_sidebar_widget” before the script containing it has been loaded. Using the ‘plugins_loaded’ action hook to run the init function ensures that everything loads in the right order first.
The lines surrounding the call to nifty_stuff are there because the widget-enabled wordpress themes may use them, and so they must be supported.
The register_sidebar_widget function associates a label for the widget with the actual widget function that will get called if the user adds it to their sidebar. That label is what the user sees in their widgets menu.
Now, that’s all well and good for really simple plugins. But if your widget needs that user input, then keep reading to learn how to add a widget control.
STEP 2: Using a control to let users configure your widget
When a widget has a control associated with it, the draggable block that represents it contains a small clickable graphic. When the user clicks on the graphic, a popup appears presenting a form through which they can specify any options available for configuring that plugin. As a developer, you need to specify the form’s contents, as well as it’s width and height. You also want to be able to process the user input and then pass it to your sidebar function.
Sticking with the example of nifty_stuff from before, let’s suppose that the nifty_stuff function needs 2 variables from the user, a word and a number. Again, we’ll look at the code that accomplishes this, and then I’ll explain how it works.
function widget_nifty_stuff_init() {
if (!function_exists(‘register_sidebar_widget’)) { return; }
function widget_nifty_stuff($args) {extract($args);
echo $before_widget . $before_title . $after_title;
if(!$options = get_option(‘nifty_stuff’)) $options = array(‘number’=>0, ‘word’=>”);nifty_stuff($options[‘number’], $options[‘word’]);
echo $after_widget;}
function widget_nifty_stuff_options()
{if(!$options = get_option(‘nifty_stuff’)) $options = array(‘number’=>0, ‘word’=>”);
if($_POST[‘nifty_stuff-submit’])
{$options = array(‘number’ => $_POST[‘nifty_stuff-number’], ‘word’ => $_POST[‘nifty_stuff-word’]);
update_option(‘nifty_stuff’, $options);}
echo ‘<p>Type a number:<input type=”text” name=”nifty_stuff-number” value=”‘.$options[‘number’].'” id=”nifty_stuff-number” /></p>’;echo ‘<p>Type a word:<input type=”text” name=”nifty_stuff-word” value=”‘.$options[‘word’].'” id=”nifty_stuff-word” /></p>’;
echo ‘<input type=”hidden” id=”nifty_stuff-submit” name=”nifty_stuff-submit” value=”1″ />’;
}
register_sidebar_widget(‘Nifty Stuff’,’widget_nifty_stuff’);
register_widget_control(‘Nifty Stuff’,’widget_nifty_stuff_options’, 200, 200);}
add_action(‘plugins_loaded’, ‘widget_nifty_stuff_init’);
DOWNLOAD EXAMPLE SOURCE
if(!$options = get_option('nifty_stuff')) $options = array('number'=>0, 'word'=>'');
In this case, the function “get_option” returns an array containing the information sent by the “update_option” call (further down), or else ‘false’ if it’s never been set. You may recognize “get_option” for its more common usage – retrieving information about the blog itself, such as ‘date_format’, ‘siteurl’, or ‘admin_email’ – things set under the options tab. In this case we’re just expanding on that functionality. It’s not the only way we could do this, it’s just the easiest. You can put all your user input into a single option array, or you can break them up into multiple options. Just be sure to use unique names that could only be associated with your widget, or you risk introducing compatibility issues.
function widget_nifty_stuff_options()
{
if(!$options = get_option('nifty_stuff')) $options = array('number'=>0, 'word'=>'');
In order for nifty_stuff to get its proper arguments, now we turn our attention to the control function. First the control function retrieves the options. If they’ve never been set, it just uses ‘0’ for the number, and an empty string for the word. It uses these values in order to populate the form fields that the user sees.
if($_POST['nifty_stuff-submit'])
{
$options = array('number' => $_POST['nifty_stuff-number'], 'word' => $_POST['nifty_stuff-word']);
update_option('nifty_stuff', $options);
}
If the user has just posted new information, the $options array takes on those new values and the ‘nifty_stuff’ option gets updated.
The next section (not copied for sake of brevity) defines the form fields that the user should see when they click on the control. Just use regular html code, but don’t add the form tag, since WordPress will supply that when it displays your fields. Notice the hidden field ‘nifty_stuff-submit’. It’s only purpose is to provide a testable condition so your control function knows whether or not the form has been submitted.
register_sidebar_widget('Nifty Stuff','widget_nifty_stuff');
register_widget_control('Nifty Stuff','widget_nifty_stuff_options', 200, 200);
The function ‘register_widget_control’ requires that you use the same name in the first parameter as you use for the first parameter of the ‘register_sidebar_widget’ function. The second parameter is the name of the control function. The next parameters – width and height measured in pixels, are optional. If you do not specify them, width defaults to 300 pixels, and height defaults to 200.
Nifty Stuff in action:
September 30 2007 11:19 pm | open-source and technical articles
4 Responses to “Turning a WordPress Sidebar Plugin Into a Widget”
music on 08 Jan 2008 at 10:12 pm #
very interesting.
i’m adding in RSS Reader
baterismos on 15 Oct 2008 at 11:28 am #
Great article. I had to laugh at the first, function, though (widget_nifty_stuff_init), which sounded like “Widget Nifty Stuff, Innit?”
Michael Carter on 31 Oct 2011 at 11:52 pm #
Working on getting through the process. I like the idea but weak in coding. So, do I have the right to ask what will seem a ridiculous question? … Maybe.
I’ve read about and experienced the slow down in performance caused by too many plugins. There are about 20 what in a ‘basic’ set that are used on every site I create. Is it feasible to integrate these into the theme by making these functions and calling them as part of the theme rather than as plugins (no plugin, just a call to the code)? OR would this have the result, the same time amount, so why bother? I’m asking if dumping the plugin from the Plugins Page would inherently have any beneficial result. There, told you it was nuts.
Thanks
admin on 03 Nov 2011 at 3:13 am #
Oh gosh, this post was written back when widgets were a brand new feature and the lack of documentation was driving me nuts. At the time, I don’t know that themes even supported widgets. Whew – blast from the past!
As to your question, you need to step back and consider that WordPress is basically a layout management framework. Think of every plugin, widget, and theme as residing in a box called WordPress. Moving a plugin from a standalone to part of your theme might make a lot of organizational sense and add value that way, especially if it means you can deploy new blogs faster, but it’s not going to be any faster as far as how long it takes the blog itself to load up in a browser. So, would it have ANY beneficial result? Sure, maybe. But it won’t improve the performance of your sites.