WordPress Plugin Bootcamp Part 2 – Pages,Widgets & Options

wpplugins

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
add_action('init','register_webitect_widget');

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

Adding Widget Controls

widgets
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

wp-admin
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
add_action('admin_init','add_WebitectPlugin_option_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

wordpress
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!

 

Written By Nick Parsons

Nick is the editor of Webitect and a developer + designer from Houston TX.

6 Comments

  1. Ann

    January 26th, 2010 at 12:56 pm

    Nick,

    Thanks a lot for these tutorials–they seem to be just what I’m looking for.

    By any chance, do you have a complete working version of the widget code above? I’m trying to follow along with it, but I’m not getting the expected results. I must be missing something.

    Thanks!

  2. Mike Smith

    February 11th, 2010 at 06:05 pm

    I’ve been following the tutorials, but when I set up the widget, it doesn’t show any options in the widget box in the backend of the site. Any idea why?

  3. Nick Parsons

    February 11th, 2010 at 07:54 pm

    @Mike Smith:
    Thanks for asking!

    I’d have to see your code to be sure, but remember that you have to echo any output in your widget display function (webitect_widget_control in the example).

    For example, if you want a text input field to show up inside the options box, you have to echo that inside the function.

    If that doesn’t help you, maybe you can send me your code and I can look over it. Thanks again for asking!

  4. Wordpress affiliate

    June 3rd, 2010 at 03:23 am

    I’m having plenty of difficulty subscribing for your rss feed, it keeps giving me an error for some reason.

  5. Stephanie

    December 14th, 2010 at 03:24 pm

    UPDATE: in WordPress 3.0, you should use “wp_register_widget_control(id, name, callback_function)” to create the controls. Note the addition of “wp_” to the function name and the id as a parameter.

  6. Chris Strutton

    June 3rd, 2011 at 04:30 pm

    I am trying to modify the FAQ Manager plugin to allow me to tweak details of the widgets from an admin page. (the Weaver theme admin pages are the inspiration). If I set a number of options on my custom admin page that I add to the plugin, how do I access them in the widget code?
    Thanks in advance
    Chris

What Do You Think?