WordPress.org

Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Example Dashboard Widget

Introduction

Working with dashboard widgets can be daunting to those unfamiliar with some of WordPress's inner workings, like the Options API. This article demonstrates an full-featured dashboard widget plugin (including configuration options).

This article assumes that you are proficient with PHP and already somewhat familiar with how WordPress plugins work. A familiarity with the Dashboard Widgets API is helpful, but not required.

This Dashboard Widget will include 3 files: one class, and two "template" files, all in one directory called example_dashboard_widget.

The Core Class

First, let's start by creating the core class in our example_dashboard_widget folder. Name the file *example_dashboard_widget.php* (remember that plugin's root php file should have the same name as the plugin directory).

Place the following the newly created php file:

<?php
/*
Plugin Name: Example Dashboard Widget
Plugin URI: http://codex.wordpress.com/Example_Dashboard_Widget
Description: Demonstrates how to add a simple dashboard widget
Version: 1.0
Author: My Name
Author URI: http://example.com/
License: GPLv2 or later
*/
add_action('wp_dashboard_setup', array('My_Dashboard_Widget','init') );

class My_Dashboard_Widget {

    /**
     * The id of this widget.
     */
    const wid = 'my_widget_example';

    /**
     * Hook to wp_dashboard_setup to add the widget.
     */
    public static function init() {
        //Register widget settings...
        self::update_dashboard_widget_options(
            self::wid,                                  //The  widget id
            array(                                      //Associative array of options & default values
                'example_number' => 42,
            ),
            true                                        //Add only (will not update existing options)
        );

        //Register the widget...
        wp_add_dashboard_widget(
            self::wid,                                  //A unique slug/ID
            __( 'Example Dashboard Widget', 'nouveau' ),//Visible name for the widget
            array('My_Dashboard_Widget','widget'),      //Callback for the main widget content
            array('My_Dashboard_Widget','config')       //Optional callback for widget configuration content
        );
    }

    /**
     * Load the widget code
     */
    public static function widget() {
        require_once( 'widget.php' );
    }

    /**
     * Load widget config code.
     *
     * This is what will display when an admin clicks
     */
    public static function config() {
        require_once( 'widget-config.php' );
    }

    /**
     * Gets the options for a widget of the specified name.
     *
     * @param string $widget_id Optional. If provided, will only get options for the specified widget.
     * @return array An associative array containing the widget's options and values. False if no opts.
     */
    public static function get_dashboard_widget_options( $widget_id='' )
    {
        //Fetch ALL dashboard widget options from the db...
        $opts = get_option( 'dashboard_widget_options' );

        //If no widget is specified, return everything
        if ( empty( $widget_id ) )
            return $opts;

        //If we request a widget and it exists, return it
        if ( isset( $opts[$widget_id] ) )
            return $opts[$widget_id];

        //Something went wrong...
        return false;
    }

    /**
     * Gets one specific option for the specified widget.
     * @param $widget_id
     * @param $option
     * @param null $default
     *
     * @return string
     */
    public static function get_dashboard_widget_option( $widget_id, $option, $default=NULL ) {

        $opts = self::get_dashboard_widget_options($widget_id);

        //If widget opts dont exist, return false
        if ( ! $opts )
            return false;

        //Otherwise fetch the option or use default
        if ( isset( $opts[$option] ) && ! empty($opts[$option]) )
            return $opts[$option];
        else
            return ( isset($default) ) ? $default : false;

    }

    /**
     * Saves an array of options for a single dashboard widget to the database.
     * Can also be used to define default values for a widget.
     *
     * @param string $widget_id The name of the widget being updated
     * @param array $args An associative array of options being saved.
     * @param bool $add_only If true, options will not be added if widget options already exist
     */
    public static function update_dashboard_widget_options( $widget_id , $args=array(), $add_only=false )
    {
        //Fetch ALL dashboard widget options from the db...
        $opts = get_option( 'dashboard_widget_options' );

        //Get just our widget's options, or set empty array
        $w_opts = ( isset( $opts[$widget_id] ) ) ? $opts[$widget_id] : array();

        if ( $add_only ) {
            //Flesh out any missing options (existing ones overwrite new ones)
            $opts[$widget_id] = array_merge($args,$w_opts);
        }
        else {
            //Merge new options with existing ones, and add it back to the widgets array
            $opts[$widget_id] = array_merge($w_opts,$args);
        }

        //Save the entire widgets array back to the db
        return update_option('dashboard_widget_options', $opts);
    }

}

The Widget

Basic widgets (those with no configuration options) may only need one template. The following file is called *widget.php* and is automatically required by the above the core class.

By requiring another file as a template (instead of simply placing the following in the class), we can keep all the HTML and presentation code separate, making our core class easier to read and our template easier to edit and maintain.

We also have access to all our class methods via self::method_name();

<?php
/**
 * This file could be used to catch submitted form data. When using a non-configuration
 * view to save form data, remember to use some kind of identifying field in your form.
 */
?>
<p>This is an example dashboard widget!</p>
<p>This is the front-facing part of the widget, and can be found and edited from <tt><?php echo __FILE__ ?></tt></p>
<p>Widgets can be configured as well. Currently, this is set to <b><?php echo self::get_dashboard_widget_option(self::wid, 'example_number'); ?></b> ! To change the number, hover over the widget title and click on the "Configure" link.</p>

Also note that we make use the self::wid constant (which we defined in our core class) instead of typing the name of the widget. This makes a number of things much simpler, especially when used in the configuration template (see below).

Widget Configuration

Developers can also give admins "configuration" options for their Dashboard widgets. Our core class already added support and will attempt to load a separate configuration file for us. That file should be called *widget-config.php* and should contain the following...

<?php
/**
 * This file could be used to catch submitted form data. When using a non-configuration
 * view to save form data, remember to use some kind of identifying field in your form.
 */
if (!empty($_POST)) {  
    $number = ( isset( $_POST['number'] ) ) ? stripslashes( $_POST['number'] ) : '';
    self::update_dashboard_widget_options(
            self::wid,                                  //The  widget id
            array(                                      //Associative array of options & default values
                'example_number' => $number,
            )
    );
}

?>
<p>This is an example dashboard widget!</p>
<p>This is the configuration part of the widget, and can be found and edited from <tt><?php echo __FILE__ ?></tt></p>
<input type="text" name="number" value="<?php echo self::get_dashboard_widget_option(self::wid, 'example_number'); ?>" /><br />

Related