Tags – ,

A Quick Guide to Creating Custom WordPress Widgets

Widgets can be useful for displaying posts, featuring products, showing Twitter feeds, linking to other websites and a whole lot more! A vanilla WordPress install comes with 12 widgets. In many cases, however, websites will demand more.

In this article, I’ll show you the basics of creating widgets for yourself or your clients, so that you can provide better functionality in your work.

Widget Basics

Widgets are most commonly created by plugins. While they can technically be created from a theme, it’s much better practice to create a dedicated plugin for your widget. Creating a plugin is much easier than you might realize, so let’s go through the process in a nutshell.

Creating A Plugin

First, create a folder in your WordPress installations plugin folder; by default this is wp-content/plugins. Your plugin name should be unique across all the plugins in the WordPress ecosystem. In other words, don’t name your plugin something generic like Twitter Widget; try prefixing it to make it more unique. For our test, create a folder named my-widget and in that folder create my-widget.php. Inside this file, add the following code:

<?php 
/*
Plugin Name: My Plugin
Version: 1.0
Plugin URI: http://danielpataki.com
Description: The descripion of your plugin.
Author: Daniel Pataki
Author URI: http://danielpataki.com/
*/

Once you save the file, you should be able to go to the plugins section in WordPress and activate the plugin. It won’t do anything just yet, but we’ll learn how to add functionality soon!

In case you’re wondering, the reason this is best done in a plugin has to do with the role of themes versus plugins. Themes are meant to style your website; plugins are meant to add functionality. To put it another way: If you create a Twitter widget, you’ll probably want to keep using it even if you switch themes.

A Widget Skeleton

Widgets are actually classes that extend the WP_Widget class. This sounds more complex than it is — you don’t need to understand object-oriented programming to create widgets. Here’s the widget skeleton, and I explain it in detail below.

add_action( 'widgets_init', 'my_widget_init' );

function my_widget_init() {
    register_widget( 'my_widget' );
}

class my_widget extends WP_Widget
{

    public function __construct()
    {
        $widget_details = array(
            'classname' => 'my_widget',
            'description' => 'My plugin description'
        );

        parent::__construct( 'my_widget', 'My Widget', $widget_details );

    }

    public function form( $instance ) {
        // Backend Form
    }

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

    public function widget( $args, $instance ) {
        // Frontend display HTML
    }

}

So, first of all, we need to let WordPress know that we want to add a widget. This is why we hook a function into widgets_init and use register_widget() within that function. By giving our widget’s class name to the function, we can get WordPress to initialize it when needed.

Within the widget class, we have four functions. The __construct() function takes care of setting up our widget. The base class WP_Widget does the heavy lifting; we just give it a few details like the class name and description.

The form() function is responsible for displaying the form within the widget. This shows up on the backend and lets users set up the widget.

The update() function contains some logic that is applied to the data in the form before it’s saved. For simple cases, this isn’t really needed so we can just return the $new_instance and all will be well. If you need to transform user data, compare it with the old instance or calculate something from the data, you can use this function. One good example of this is pulling in images from a Flickr account. The user specifies an account, and when the form is saved, we pull in 10 images and cache them.

The widget() function is what displays our form on the front end. It receives the arguments of the widget area (these can be specified when creating sidebars) and the instance variable, which contains the information from our form.

The Widget Creation Process

As you can see this is fairly simple, so let’s look at a quick example which would allow us to show a simple title and a paragraph of text. Since these are simple bits of data we don’t need to bother with the update() function, we just need to create the form and then display the results on the front-end. Here’s how it would look:

public function form( $instance ) {
    $title = '';
    if( !empty( $instance['title'] ) ) {
        $title = $instance['title'];
    }

    $text = '';
    if( !empty( $instance['text'] ) ) {
        $text = $instance['text'];
    }

    ?>

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

    <p>
        <label for="<?php echo $this->get_field_name( 'text' ); ?>"><?php _e( 'Text:' ); ?></label>
        <textarea class="widefat" id="<?php echo $this->get_field_id( 'text' ); ?>" name="<?php echo $this->get_field_name( 'text' ); ?>" type="text" ><?php echo esc_attr( $text ); ?></textarea>
    </p>

    <div class='mfc-text'>
        
    </div>

    <?php

    echo $args['after_widget'];
}

Inside the form, we create two variables, one for the text, one for the title. We need to make sure that if there’s a value in the $instance array for these elements when we use them. These values exist if the widget has already been saved.

Use the get_field_name() and get_field_id() function to output the id and name of fields. WordPress handles multiple sidebars and widgets, so it’ll add its own stuff to the name of the field.

In the widget() function it’s advisable to use the values in the $args array to display content that is meant to be shown before/after the widget itself and before/after the title. There’s a default for these (usually HTML wrapper elements) but it can also be specified by the theme when adding sidebars. If you want your plugin to play nice with others, this is a must.

Finally, just use the values in the instance variable to create the HTML required for your plugin.

Conclusion

As you can see, creating a widget is pretty easy. For all intents and purposes, the grunt work is shared by only two functions — one for creating the form, the other for displaying saved form data.

You can use scripts and styles to make more elaborate widgets — both in the front and back ends. If you create something particularly useful, upload it to the Plugin Repository. It’s great practice, and you just might help out someone else in the process!

Tweet about this on TwitterShare on FacebookGoogle+Share on LinkedInEmail to someone

By Daniel Pataki

Hello, my name is Daniel. I build plugins, themes and apps – then proceed to write or talk about them. I'm the editor for the WordPress section on Smashing Magazine and I write for a bunch of other online magazines. When not coding or writing you'll find me playing board games or running with my dog. Drop me a line on Twitter or visit my personal website.
Comments (policy)
  • Hi! Thank you but how can we show title and text into frontend? :)

  • Anyone but Obama

    An example would have been nice to show what it looks like. You might get some people actually doing it. Almost a year and onlu ONE comment is probably because people don’t know what it looks like.

  • Christian Saborio

    Thanks for this…I think you did a superb job explaining it, it made sense to me, but as someone pointed out, some images on what it should like like would’ve made it easier for non-experienced users. Cheers!

  • Olisa

    Just made one. Thanks to you!

  • the content explained above is great for the initial learners..to guide

More in Code, Widgets
Super-handy jQuery code snippet to run JavaScipt after a complete page has loaded

Nothing to do with WordPress directly but if you're looking to run some JavaScript in a template/file somewhere AFTER everything on a page has completely...

Close