WordPress Plugin Bootcamp Part 2 – Pages,Widgets & Options


Yesterday we looked at the basics of plugin building - and found out how to define a plugin, use action/filter hooks, and add scripts. Today, you'll  learn how to add custom widgets, create a plugin options page, and learn how WordPress's option-saving mechanism works.

Come check it out, and learn some more about how to build your own WordPress plugin!

 First Up: Defining Custom Widgets

A few extra features can really take a  plugin from good to great, and having a custom widget is one of them. In fact, the whole purpose of some plugins revolves around custom widgets. Since the advent of widgetized themes, widgets have increasingly improved the expressiveness of WordPress, which means that custom widgets is a good place to start our second lesson.

As you might expect, there is a cool function which allows us to add custom widgets very easily. It's called wp_register_sidebar_widget(). It accepts 4 arguments:

  • id-can be either an integer or a string. It's a required arg which you can use to reference the widget later.
  • name- this is the widget's 'pretty name', the one that will be displayed on the widgets admin page
  • callback-a function name, defined in your plugin file, which should echo the output of the widget
  • options- an array or string of default options for the widget. The most useful is description, which will also be shown on the widgets admin page

The widget callback function is passed a set of parameters - remember how you can define custom params for register_sidebar in functions.php? That's them. That same associative array that you (or another theme developer) gave to register_sidebar is now given to wp_register_sidebar_widget. Unless you want to make people mad, you have to make sure to include that data in the markup your plugin outputs to avoid breaking the theme.

Here's some example code that registers a custom widget (put together from everything you've learned so far):

function register_webitect_widget(){
$options = array('description' => 'Custom Webitect widget for displaying Webitect's best posts.');
wp_register_sidebar_widget('webitect','Webitect Display','display_webitect_widget',$options);
function display_webitect_widget($theme_info){
echo $theme_info['before_widget'];
echo $theme_info['before_title'] . "Webitect's Best Posts" . $theme_info['after_title'];
echo $theme_info['after_widget'];
//init is a good time to register widgets

One more thing- there is a matching, opposite function called wp_unregister_sidebar_widget, should you ever need it.

Adding Widget Controls

So that's great, but what about when you want to give the user more control over the widget? The answer lies in register_widget_control(). You know how on the widgets admin page most active widgets have an expandable area with options fields? Let's change that function we made called register_webitect_widget to create a widget control as well:

function register_webitect_widget(){
$options = array('description' => 'Custom Webitect widget for displaying Webitect's best posts.');
wp_register_sidebar_widget('webitect','Webitect Display','display_webitect_widget',$options);
register_widget_control('Webitect Display','webitect_widget_control');
//Now create the webitect_widget_control function:
function webitect_widget_control(){
echo "
"; echo " }

As you can see, this function (register_widget_control) has 2 arguments - the name of the widget and the name of the callback function. Whatever the callback function outputs will be wrapped in a form that has a built-in submit button and is all set to submit correctly, so you don't have to output any form tags or a submit button - just selectboxes, text inputs, etc.

What you should do inside your callback function is check to see if the widget control form has been submitted. If it is, it's time to save the data, which brings us to our next item - saving/retrieving WordPress options.

WordPress's Option Mechanism

WordPress' option mechanism is very easy to use and to the point. In fact, I don't think it could be any simpler. There are two option related functions, one for retrieving (get_option()) and one for sending (update_option()). You can set options on pretty much anything that you need to save  key/value data for- the mechanism is very simple and therefore very versatile.

The key is generally named the same name as the widget/plugin for simplicity, and the value can be a string or an associative array (if you have multiple pieces of data you want to save). Let's update the webitect_widget_control function to save any submitted data:

function webitect_widget_control(){
//if new options were just submitted, save them
if( isset($_POST['webitect-num']) ){
$sent_options = array( 'num' => $_POST['webitect-num'] ); 
update_option('webitect-widget', $sent_options);
echo 'Options saved.';
//get saved options, if they exist
$saved_options = get_option('webitect-widget');
echo "
"; echo " }

Of course, you aren't limited to just widgets. Plugin options can be saved, too. As usual, the WordPress documentation has some more great info on the option functions.

The Culmination - Adding Admin Pages

And finally, today's big item: adding/manipulating admin pages. This is possible because WordPress allows us to remove, add, and reorder admin pages as we see fit. Of course, for the most part these capabilities are used for adding plugin management pages, which is what we'll be using them for today. This is such a big thing that WordPress actually provides several functions for adding pages, depending on exactly where we want them to show up. The two big ones are add_menu_page() and add_submenu_page(). They both accept 5 arguments:

  • page title - the title text to display on the page itself
  • menu-title- the name that should appear in the menu on any admin page
  • capability- the minumum user level required to access this page. See Roles and Capabilitesin the WordPress documentation.
  • file- uri to the the file that outputs the page content. If a function is supplied to do this, the file arg becomes a unique handle for the page.
  • function- the optional function that outputs the page content

add_submenu_page() also accepts one more (which comes before the other 5) - the filename of the parent page that it should appear under (users.php, plugins.php, post-new.php, etc.)

There are also several shortcut functions that you can use to add new pages more easily:

  • add_options_page - adds a link in the Options menu
  • add_theme_page - adds a link in the Appearance menu
  • add_posts_page - adds a link in the Posts menu
  • add_pages_page - adds a link in, you guessed it, the Pages menu

They all take the same 5 arguments, but allow you to easily specify submenu pages in common areas. Let's take a look at what the code might look like all put together:

function add_somePlugin_option_page(){
add_options_page('Edit Webitect Plugin Settings','Webitect Plugin', 10, 'webitect-options-panel.php');
//only go through function if we are on an admin page

What this does is create an options page (in the Options submenu), that will (when loaded) display the contents of webitect-options-panel.php. That file should have a form inside of it which will allow users to edit the plugin settings. You can read WordPress's official explanation of the general process here, as well as reading their specific directions for what to put inside of your options page file here.

Wrapping Up

There is a lot to learn about WordPress plugins, but by now you should be getting a good feel for how the API works. At this point you can define a plugin, add scripts, create widgets and plugin control pages, save and retrieve plugin/widget options and use API hooks to perform tasks and output information at the exact right spots. Tomorrow, we'll be looking at custom panels, registering shortcodes, adding tinyMCE buttons, and other Write Post hacks.

I'd love to hear any thoughts and questions!



  1. Ann January 26, 2010
  2. Mike Smith February 11, 2010
  3. Nick Parsons February 11, 2010
  4. Wordpress affiliate June 3, 2010
  5. Stephanie December 14, 2010
  6. Chris Strutton June 3, 2011

Leave a Reply