Cheap phentermine Orbitz Savings account payday loan Flomax Arizona auto insurance Vonage Debt consolidation company Full tilt poker Montelukast Furniture Phentermine 37.5 Smash repair Zovirax Tadalafil Football handicapping High stakes poker Foreclosure Sell real estate note Airline tickets Ephedrine Cholesterol Propecia online Occupational therapy Fioricet online Consolidate credit card Buy clomid Medical assistant Cheap hotels Cheapest tramadol Superbowl predictions Credit card debt relief 3 in 1 credit report What is adipex House Auto owner insurance Get viagra Allergy Paint Lorazepam Super bowl props Accutane Sildenafil citrate Buy paxil Casino portal Instant payday loan Cialis levitra Tamoxifen Super bowl pool Pharmacies Cheap carisoprodol Tramadol ultram Porn Get out of debt Clarithromycin Buy generic viagra Online payday loan Virus and spyware protection Cardiology Car insurance quote Build 

Create multi instances widget

datePosted on 12:39, July 6th, 2008 by Millan

Warning: gmdate() expects parameter 2 to be long, string given in /home8/gdstarra/public_html/gdragon/subdomain_wp/wp-content/plugins/wp-downloadmanager/wp-downloadmanager.php on line 1009

Warning: gmdate() expects parameter 2 to be long, string given in /home8/gdstarra/public_html/gdragon/subdomain_wp/wp-content/plugins/wp-downloadmanager/wp-downloadmanager.php on line 1010

Since I have started developing my ‘GD Pages Navigator’ widget plugin, I wanted to upgrade it so it can support more then one instance on a page. Unfortunatly there are limited resources available for that task, and almost no info about it in the official documentation. There are plugins that use different methods of achiving this, but best method is the one used by plugins build into Wordpress.

So, my starting point was ‘widget.php’ file where this default widgets are located. They also provided a short example of multi instance widget at the end of this file. This example in is good, but it has few errors (copy-paste errors mostly). This function is in the sample code class

I have decided to walk you throught the process of creating a widget that will support more then one instance. This example will show you how to work with different types of settings and it will provide you with some practicle code snippets you can use in your own plugins. Tutorial will be based on my ‘GD Pages Navigator’ plugin. This widget supports multiple instances from the version 3.0.0.

Wordpress Widgets Page

This page is used to handle setting widgets on sidebars. Once loaded this page shows all available widgets and widgets used by the currently active sidebar. When you save changes you made, complete page contents is posted back to the server. Then ‘widegt.php’ is called twice: first to process posted data, second is 302 redirect to display page to the user and show update message.

Each form element for your widget control should have unique name, but for multi instance support you need to make this a bit different. Wordpress will generate unique ID’s for each instance of widget used.

Basic Widget Structure

First, in Wordpress plugins folder create folder ‘gd-multi’. This will be folder for your plugin. Create 3 files there:

  1. gd-multi.php: main widget file
  2. gd-multi.css: optional, if you want to style your widget control
  3. gd-multi.js: optional, if you need javascript functions in the widget control

Code bellow represents basic widget class that goes into ‘gd-multi.php’ file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class GDMulti {
    var $plugin_folder = '';
    function GDMulti() {
        $this->plugin_folder = get_option('home').'/'.PLUGINDIR.'/gd-multi/';
        add_action('admin_head', array(&$this, 'admin_head'));
    }
 
    function admin_head() {
        echo('<link rel="stylesheet" href="'.$this->plugin_folder.'gd-multi.css" type="text/css" media="screen" />');
        echo('<script type="text/javascript" src="'.$this->plugin_folder.'gd-multi.js"></script>');
    }
 
    function init() {
    }
 
    function widget($args, $widget_args = 1) {
    }
 
    function control($widget_args = 1) {
    }
}
 
$gdm = new GDMulti();
add_action('widgets_init', array($gdm, 'init'));</link>

If you don’t need CSS or JS, you can remove action from constructor, and ‘admin_head()’ method. Init() method will be used to initialize one or more instances of the widget. Widget() method is actual rendering of the widget contents on the blog pages sidebar(s). Control() method will contain code for displaying and handling adding and settings of the widget. Admin_head() method is used to add stylesheet and jasvascript to be loaded on administration pages, so you can ues them in the widget control dialog.

Storing Widget Settings

Main problem with multi instance widgets is saving their settings. You need to have a way of storing individual settings for each widget instance. The best way is to use an array based on widget id, and for each widget instance you have one array element. This one element can also be a array because you will usually have more then one setting you need to store for the widget.

Our sample widget will have 3 options we will need to save:

  • Widget title: title
  • List of pages to show: pages
  • Sort order: sort

We will need default settings stored, beacuse that will make it easier to handle later. So single widget settings array will look like this:

1
2
3
4
5
    var $default_options = array(
            'title' => 'Pages', 
            'pages' => '',
            'sort' => 'ASC'
    );

All settings will ne stored in the another array, where each element of the array will be array like one we have created above.

Initializing Widget

Widget init code is used to register one or more instances of the widget plugin depending how many of them you want to use. To do this we will use this complet code for init() method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    function init() {
        if (!$options = get_option('widget_gd_multi'))
            $options = array();
 
        $widget_ops = array('classname' => 'widget_gd_multi', 'description' => 'GD Multi');
        $control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'gdmulti');
        $name = 'GD Multi';
 
        $registered = false;
        foreach (array_keys($options) as $o) {
            if (!isset($options[$o]['title']))
                continue;
 
            $id = "gdmulti-$o";
            $registered = true;
            wp_register_sidebar_widget($id, $name, array(&$this, 'widget'), $widget_ops, array( 'number' => $o ) );
            wp_register_widget_control($id, $name, array(&$this, 'control'), $control_ops, array( 'number' => $o ) );
        }
        if (!$registered) {
            wp_register_sidebar_widget('gdmulti-1', $name, array(&$this, 'widget'), $widget_ops, array( 'number' => -1 ) );
            wp_register_widget_control('gdmulti-1', $name, array(&$this, 'control'), $control_ops, array( 'number' => -1 ) );
        }
    }

On lines 5 and 6 we are setting options needed for registering widget, and we use them in lines 16, 17 and 20, 21. Variable $o is widget id that will be set by wordpress once we add widget to the sidebar. If no widgets are registered, then default id will be 1. Wordpress register sidebar method will call method widget(), and registering control will use control() method.

Widget Control

The code that follows goes into control() method. First we need to get widget number and initialize options if they are not initialized already. Similar code will be used in the widget rendering method.

1
2
3
4
5
6
7
8
9
10
        global $wp_registered_widgets;
        static $updated = false;
 
        if (is_numeric($widget_args))
            $widget_args = array('number' => $widget_args);
        $widget_args = wp_parse_args($widget_args, array('number' => -1));
        extract($widget_args, EXTR_SKIP);
        $options_all = get_option('widget_gd_multi');
        if (!is_array($options_all))
            $options_all = array();

And now to the most important part of the widget control. This part will be executed only after user saves sidebar widgets. We will then search through widgets registered in sidebar to get all instances of our plugin. If we found instance in the sidebar, but not in the post, we will remove that instance from the sidebar. After that we go thorught the post elements of our widget, and save them into an array, and update widget options. Complete code for this is in the next block.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
        if (!$updated && !empty($_POST['sidebar'])) {
            $sidebar = (string)$_POST['sidebar'];
 
            $sidebars_widgets = wp_get_sidebars_widgets();
            if (isset($sidebars_widgets[$sidebar]))
                $this_sidebar =& $sidebars_widgets[$sidebar];
            else
                $this_sidebar = array();
 
            foreach ($this_sidebar as $_widget_id) {
                if ('widget_gd_multi' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number'])) {
                    $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
                    if (!in_array("gdmulti-$widget_number", $_POST['widget-id']))
                        unset($options_all[$widget_number]);
                }
            }
            foreach ((array)$_POST['widget_gd_multi'] as $widget_number => $posted) {
                if (!isset($posted['title']) && isset($options_all[$widget_number]))
                    continue;
 
                $options = array();
 
                $options['title'] = $posted['title'];
                $options['pages'] = isset($posted['pages']) ? implode(',', $posted['pages']) : ''; 
                $options['sort'] = $posted['sort'];
 
                $options_all[$widget_number] = $options;
            }
            update_option('widget_gd_multi', $options_all);
            $updated = true;
        }

After that we need to display control form for the widget. If the widget is new instance without wisget id we will use default settings, if not, then settings will be read from saved options. After that we show the form. Form goes into sepparate file ‘gd-multi-form.php’.

1
2
3
4
5
6
7
8
9
        if (-1 == $number) {
            $number = '%i%';
            $values = $this->default_options;
        }
        else {
            $values = $options_all[$number];
        }
 
        include("gd-multi-form.php");

If you wonder what is ‘%i%’, don’t wonder any more. This value will be replaced by Wordpress javascript code with real generated widget id once we add the widget into the sidebar.

Widget Control Form

gdmulti.png

For the form elements you can use anything for id attribute, but name attribute must be in the format specified in the the example. That way once we get posted data, we can access them as they were in array based on the widget name, widget id and actual values.

For a pages selection list we use an additional function ‘render_options()’ in the main class for rendering pages options.

Each form element has a name attribute in the following form:
widget_gd_multi[widget_id][option]

Not to waste too much space in the article, complete form (it’s really simple as you can see on the picture) is in the sample download file.

Widget Output

Finally, we need to display our widget(s) in the sidebars for your visitors to see. This code is all in widget(). Each instance of the widget has it’s own settings in main otpions array. First we need to get that individual instance array. For this we can use the same code as in the control method. After that we use one new method to render pages according to selection.

Download source code

I have compiled the files we have created and changed in this article, so you can see complete code you can test and play with.

  Tutorial Multi Widget Sourcecode (4.3 KiB, 772 hits)
You need to be a registered user to download this file.

Conclusion

So, I hope you find this article useful. If you have any suggestion on improving it, or make some change if you notice some errors, please leave a comment.

VN:R_N [1.1.7_509]
Rating: 10.0/10 (1 vote cast)
  • StumbleUpon
  • TwitThis
  • Technorati
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Fleck
  • YahooMyWeb
  • Live
  • Sphinn
  • co.mments
  • LinkedIn
  • MySpace
  • E-mail this story to a friend!
  • Reddit
categoryPosted in Plugins, Tutorials | printPrint
Related Posts:

2 Responses to “Create multi instances widget”

  1. Gino123412 on October 25th, 2008 at 2:15 am

    Where can I download sourcecode

    VN:R_N [1.1.7_509]
    Rating: 0.0/5 (0 votes cast)
  2. Millan on October 26th, 2008 at 1:57 pm

    Link was lost somehow, I have added link again in the post.

    VN:R_N [1.1.7_509]
    Rating: 0.0/5 (0 votes cast)

Leave a Reply

You must be logged in to post a comment.