The simpliest way of creating a widget in WordPress 2.8+

And dis­sec­ted at that

widget-postheader

If you have even a tini­est bit of ambi­tions, you will want to have some spe­cial inform­a­tion in your blog’s side­bar, be it a link to your RSS feed or links to your co-authors’ social pro­files. Plu­gins are a nice way to get what you want, but they don’t always match your needs. For some pur­poses you will want to have your own wid­get, and cre­at­ing one in Word­Press higher than 2.8 is pretty damned easy, which I will demon­strate you in this not-anime-related-at-all post.

You have two places where you can put your widget’s code in: your theme’s functions.php or into a plu­gin. It’s pretty equal where you put it.

The Base

The whole wid­get, as gladly imple­men­ted in Word­Press 2.8, is situ­ated in a PHP class. Gladly because it’s much, much sim­pler to do basic actions like giv­ing the user options and sav­ing them like that. Let’s begin the class:

1
2
3
class new_widget extends WP_Widget {
    //All below stuff will come here
}

These are some nice three lines of code. Let’s cre­ate a con­structor func­tion now. Basic­ally, it means we write a func­tion that will tell Word­Press the widget’s unique ID, its name and its descrip­tion. Be care­ful choos­ing the ID, because for one it should be unique to not con­flict with other wid­gets, and for the other if you want to pre­serve your widget’s pos­i­tion in the side­bar as well as its set­tings you will have to bear with that same ID for ever.

Who are you, widget-chan?

1
2
3
4
    function new_widget() {
        $ops = array('classname' => 'new_widget', 'description' => 'This is your newly created widget!');
        parent::WP_Widget('new_widget', $name = 'New widget', $ops);   
    }

The $ops array con­tains the options for the wid­get. ‘Class­name’ defines what class attrib­ute the widget’s con­tainer will have. And ‘descrip­tion’ is what help text will be shown to the user on the Wid­gets page. The first param of the WP_Widget call is the unique ID I talked about before, the $name is the title that will be shown to the user on the Wid­gets page, and $ops is the call to the options above.

Giv­ing the user a choice

But don’t you think the user should have some voice too? If you want your wid­get to have cus­tom­iz­able options, you will need this function:

1
2
3
4
5
6
    function form($instance) {             
        $title = esc_attr($instance['title']);
        ?>
            <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></label></p>
        <?php
    }

This is a bit more dif­fi­cult to explain since it’s a lot of code, but prac­tic­ally, to add new text fields you just have to copy the <p></p> sequence and change ‘title’ to whatever you want. Also, to secure your/user’s data­base, run the options val­ues through the esc_attribute func­tion like with the $title above.

Sav­ing the customizations

To save the updated options into the data­base, we need this little function:

1
2
3
    function update($new_instance, $old_instance) {        
        return $new_instance;
    }

The wid­get itself

That allows some fil­ter­ing in case you want to. But hell, we’ve gone through all these func­tions, but where’s the actual wid­get?! This in its most basic form simple func­tion does the magic:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    function widget($args, $instance) {    
        extract($args);
        echo $before_widget;
        if(!empty($instance['title'])):
            echo $before_title
            . $instance['title']
            . $after_title;
        else:
            echo $before_title
            . 'Unnamed widget'
            . $after_title;
        endif;
        echo 'The contents';
        echo $after_widget;
    }

The two argu­ments the func­tion takes are the theme-specific set­tings and the user-customized options from the Wid­gets page. To sim­plify their use and refrain from writ­ing e.g. $args[’before_title’], we extract the former, which makes the array access­ible via e.g. $before_title. Everything yours must be wrapped inside $before_widget and $after_widget, and the widget’s (in our case the cus­tom­ized) title must be wrapped inside $before_title and $after_title if you don’t want to screw up the side­bar and the theme in gen­eral. In our vari­ant of the func­tion, it prints the cus­tom­ized title in case it’s set and our pre-defined one in case not, after what it prints some Hello World text (‘The con­tents’). Instead of the lat­ter you can do whatever you want. That’s all. Simple, didn’t I say that?

The wid­get, it exists!

The only thing that’s left to do to have this wid­get on your Wid­gets page is to tell Word­Press it exists. For that pur­pose, we have to call an action hook out­side of the class like this:

1
add_action('widgets_init', create_function('', 'return register_widget("new_widget");'));

There are many vari­ants of that last piece of code in dif­fer­ent tutori­als, and the most dif­fer in what action hook is actu­ally to be called, but this is the best and right one.

Sum­mary

Now, the code as it should look complete:

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
32
33
34
35
36
37
class new_widget extends WP_Widget {

    function new_widget() {
        $ops = array('classname' => 'new_widget', 'description' => 'This is your newly created widget!');
        parent::WP_Widget('new_widget', $name = 'New widget', $ops);   
    }

    function widget($args, $instance) {    
        extract($args);
        echo $before_widget;
        if(!empty($instance['title'])):
            echo $before_title
            . $instance['title']
            . $after_title;
        else:
            echo $before_title
            . 'Unnamed widget'
            . $after_title;
        endif;
        echo 'The contents';
        echo $after_widget;
    }

    function update($new_instance, $old_instance) {        
        return $new_instance;
    }

    function form($instance) {             
        $title = esc_attr($instance['title']);
        ?>
            <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></label></p>
        <?php
    }

}

add_action('widgets_init', create_function('', 'return register_widget("new_widget");'));

You can change the name of the new_widget class and the new_widget func­tion, but don’t for­get to change ‘new_widget’ inside the last action hook call then.

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
This entry was posted in Webdesign and tagged . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

7 Comments

  1. Ryan A 51
    Posted December 2, 2009 at 01:01 | Permalink

    Very nice! I think I’ll be includ­ing some­thing sim­ilar in Kronblr’s engine (since it is built with WP sim­il­ar­it­ies), as the class exten­sion is the way themes work atm.

    This is rather easy, good infos. Maybe I’ll make some inter­est­ing things when I find some time. ^^
    Ryan A´s last blog post: ごきげんよう

    • Gargron 484
      Posted December 3, 2009 at 19:55 | Permalink

      Kroblr? This is how you are gonna name your microb­log­ging engine? Look­ing for­ward to it. I find class exten­sions very com­fort­able too, and I (aes­thet­ic­ally) like how ‘parent::function’ calls look.^^

      Would you like me to write a plugin-from-scratch tutorial? I’m low on post ideas, so if it’s needed I’m gonna pick it up

      • Ryan A 51
        Posted December 4, 2009 at 14:45 | Permalink

        Yes, Kron­blr. There is a git­hub pro­ject for it at http://github.com/RyanAltman/kronblr you can check the theme files if you like, very simple them­ing, plu­gins too, but no wid­gets yet.

        Plu­gins aren’t as dif­fi­cult, it’s pretty straight­for­ward how to make them, but know­ing the right hooks can be a pain. Maybe if you go over some of the best hooks O.o Although, most anib­log­gers don’t mess with plugins/code >_>
        Ryan A´s last blog post: Recov­ery

        • Posted December 7, 2009 at 01:12 | Permalink

          “Plu­gins aren’t as dif­fi­cult, it’s pretty straight­for­ward how to make them, but know­ing the right hooks can be a pain. Maybe if you go over some of the best hooks O.o Although, most anib­log­gers don’t mess with plugins/code >_>”

          Ah yeah. This. Gotta agree with this. I don’t know jack shit about CSS. But this rule could be applied to said Ani-bloggers who don’t bother with CSS or cre­at­ing their own Wid­gets.
          Jubbz´s last blog post: The Dec­ade in Anime: A Ret­ro­spect – 2001

          • Eugen R. 484
            Posted December 7, 2009 at 15:56 | Permalink

            Just for polite-correctness, this is not CSS but PHP. CSS is the thing that makes my blog look like it does. PHP does the soft­ware core.

            Any­way, there are anib­log­gers who are inter­ested in this, and there are people other than from ani­sphere who could need this. If you want, you can see this post as a part of the webdesign-o-sphere.

            • Posted December 8, 2009 at 03:32 | Permalink

              Ah, that’s what you were talk­ing about.

              I still don’t know jack shit about PHP. –_–

              I’m kinda inter­ested in it, but i’m too lazy to put the time and effort into learn­ing.
              Jubbz´s last blog post: Biri Biri Show epis­odes 9 & 10

              • Eugen R. 484
                Posted December 9, 2009 at 20:13 | Permalink

                It’s pretty simple at the begin­ning, I could post some begin­ner tutorials.

One Trackback

  1. By Vote on this article at blogengage.com on December 1, 2009 at 20:20

    The sim­pli­est way of cre­at­ing a wid­get in Word­Press 2.8+…

    A simple and explained tutorial of cre­at­ing wid­gets in Word­Press 2.8+.…

Post a Comment

Do not spam. Do not name yourself after website names. To have an avatar, register at gravatar. Note: your e-mail will never be published or used, it is needed only to ensure you're not a spambot.

Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Subscribe without commenting