Add custom widget to wordpress admin widget interface

WordPress is amazing content management system with lots of great builtin features and widget is one of those. WordPress installation comes with some default widgets. but some times websites or client requirements demand more than it. In this tutorial i am going to explain you to create your own widget so you can provide better functionality as per requirement. Widget is just a small piece of code that we can add in functions.PHP or we can also make a plugin of it and we can use it by just drag and drop interface in widget section of dashboard. You can add these widgets in all widgets area’s which is provided by theme which you installed. just like in sidebars or footer.

Create the widget :

To create widget, there is a small code or you can say that a structure of code that will create widget. This code contains class and functions, this class extents Wp_Widget. I will explain all code step by step. lets take a look on this widget structure.

PHP
class Profile_Widget extends WP_Widget {

   public function __construct() {
        // Constructor
    }

    public function form($instance) {
        // use to show admin widget area to accept data from admin
    }

    public function update($new_instance, $old_instance) {
        // use to Update widget old values with new values
    }

    public function widget($args, $instance) {
        // show's output of this widget.
    }

}
// end class

// init the widget - to run
add_action('widgets_init',  create_function('', 'return register_widget("Profile_Widget");'));

lets divide this code in 4 sections to understand its work.

  1. __construct() – To initiate the widget.
  2. form() – To create widget form and get data to show on frontend.
  3. update() – update widget form data.
  4. widget() – To show output on frontend widget areas.

Create class and extends to wp_widget class :

PHP
class Profile_Widget extends WP_Widget {

__construct() :

The constructor is a part of code that define widget id/slug, widget name and widget description.

PHP
public function __construct() {
    // Constructor - this constructor has 3 parameters. 
    //i.e. : widget id/slug, widget name, widget description
    parent::__construct(
        'profile-widget', 
        'Profile Widget', 
         array('description' => 'This is simple widget to display small discription of author')
    );
}

form() :

This function is create a widget in wordpress admin widget interface, this creates a form that you will enter data to display as output on front-end. I am creating profile widget so for that in my form that will contain widget title, author name, author description and author profile image.

PHP
public function form($instance) {
        // This function show's form / form fields to get data in admin widget area to show on front end.
        ?>
        <style>
            .profile_widget_fields{ width: 100%; }
            img.selected-img { width: 30%; float: left; margin-right: 10px; }
            p.img-class { width: 100%; float: left; padding-top:5px; }
            .img-label{ margin-bottom: 5px; width: 100%; float: left; }
        </style>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>">Title</label><br />
            <input type="text" name="<?php echo $this->get_field_name('title'); ?>" id="<?php echo $this->get_field_id('title'); ?>" value="<?php echo $instance['title']; ?>" class="profile_widget_fields" />
        </p>
        <p class="img-class">
            <label class="img-label" for="<?php echo $this->get_field_id('profile_image'); ?>">Profile Image</label><br />
            <img src="<?php echo $instance['profile_image']; ?>" class="selected-img" />
            <input type="text" class="img" name="<?php echo $this->get_field_name('profile_image'); ?>" id="<?php echo $this->get_field_id('profile_image'); ?>" value="<?php echo $instance['profile_image']; ?>" />
            <input type="button" class="select-img" value="Select Image" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('name'); ?>">Name</label><br />
            <input type="text" name="<?php echo $this->get_field_name('name'); ?>" id="<?php echo $this->get_field_id('name'); ?>" value="<?php echo $instance['name']; ?>" class="profile_widget_fields" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('description'); ?>">About Us</label><br />
            <textarea rows="5" name="<?php echo $this->get_field_name('description'); ?>" id="<?php echo $this->get_field_id('description'); ?>" class="profile_widget_fields" ><?php echo $instance['description']; ?></textarea>
        </p>
        <script>
            var image_field;
            jQuery(function ($) {
                $(document).on('click', 'input.select-img', function (evt) {
                    image_field = $(this).siblings('.img');
                    image_preview = $(this).siblings('.selected-img');
                    tb_show('', 'media-upload.php?type=image&TB_iframe=true');
                    return false;
                });
                window.send_to_editor = function (html) {
                    imgurl = $(html).attr('src');
                    image_field.val(imgurl);
                    image_preview.attr('src', imgurl);
                    tb_remove();
                }
            });
        </script>
        <?php
    }

to show this form proper i have added some css so you can easily get css in this function. you can see i have added some jquery code, this jquery code is to add user profile image from wordpress media uploader. In this media uploader you can add image directly from your computer or specific url from another site or from you wordpress media. To see this form function output and media uploader check below screenshots :

update() :

The update() is very simple. we just want to update all fields in instance array thats it.

PHP
public function update($new_instance, $old_instance) {
    // This function Updating widget values/data replacing old instances with new instances
    $instance = array();
    $instance['title'] = (!empty($new_instance['title']) ) ? strip_tags($new_instance['title']) : '';
    $instance['profile_image'] = (!empty($new_instance['profile_image']) ) ? strip_tags($new_instance['profile_image']) : '';
    $instance['name'] = (!empty($new_instance['name']) ) ? strip_tags($new_instance['name']) : '';
    $instance['description'] = (!empty($new_instance['description']) ) ? strip_tags($new_instance['description']) : '';
    return $instance;
}

widget() :

The widget() is to display output on the website. Its what your visitors will see. This function can be customize as per you need. you can pass css as per your theme to match output. In this function i am displaying all data which we added in form from widget interface.

PHP
public function widget($args, $instance) {
    // basic output just for this example
    echo $args['before_widget'];
    if (!empty($title))
        echo $args['before_title'] . $title . $args['after_title'];
    ?>
    <style>
        .profile_pic { width: 39%; float: left; margin-right: 15px; }
        .profile_pic img { width: 100%; border-radius: 10%; }
    </style>
    <h4 class="widget-title"><?php echo $instance['title']; ?></h4>
    <div class="profile_pic">
        <img src="<?php echo $instance['profile_image']; ?> "/>
    </div>
    <div class="profile_data">
        <p>
            <label><strong>Name : </strong><span><?php echo $instance['name']; ?></span></label>
            <label><strong>About Us : </strong><span><?php echo $instance['description']; ?></span></label>
        </p>
    </div>
    <?php
    echo $args['after_widget'];
}

The last point to cover and to run this widget. we just need to init this widget to widget_init hook. and also we want to load some js for media-uploader.

PHP
}
// end class

// init the widget - to run
add_action('widgets_init', create_function('', 'return register_widget("Profile_Widget");'));

// queue up the necessary js
function hrw_enqueue() {
    wp_enqueue_style('thickbox');
    wp_enqueue_script('media-upload');
    wp_enqueue_script('thickbox');
    // moved the js to an external file, you may want to change the path
    wp_enqueue_script('hrw', '/wp-content/plugins/profile-widget/script.js', null, null, true);
}

add_action('admin_enqueue_scripts', 'hrw_enqueue');

Output :

Conclusion :

As you can see, to make widget is not complex. we made a simple widget to show some information of author. In this tutorial we have coverd widget and some extra feature of wordpress that is media uploader. In future posts, we will explain this media uploader in more details. so stay connected with my blog to get usefull stuff in simple manner, and i will be more happy to get some feedback from you in comment section, and also share this post if you like and if it is usefull for others. Thanks.

Take all this code together – Click here
class Profile_Widget extends WP_Widget {

    public function __construct() {
        // Constructor - this constructor has 3 parameters. 
        //i.e. : widget id/slug, widget name, widget description
        parent::__construct(
                'profile-widget', 'Profile Widget', array('description' => 'This is simple widget to display small discription of author')
        );
    }

    public function form($instance) {
        // This function show's form / form fields to get data in admin widget area to show on front end.
        ?>
        <style>
            .profile_widget_fields{ width: 100%; }
            img.selected-img { width: 30%; float: left; margin-right: 10px; }
            p.img-class { width: 100%; float: left; padding-top:5px; }
            .img-label{ margin-bottom: 5px; width: 100%; float: left; }
        </style>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>">Title</label><br />
            <input type="text" name="<?php echo $this->get_field_name('title'); ?>" id="<?php echo $this->get_field_id('title'); ?>" value="<?php echo $instance['title']; ?>" class="profile_widget_fields" />
        </p>
        <p class="img-class">
            <label class="img-label" for="<?php echo $this->get_field_id('profile_image'); ?>">Profile Image</label><br />
            <img src="<?php echo $instance['profile_image']; ?>" class="selected-img" />
            <input type="text" class="img" name="<?php echo $this->get_field_name('profile_image'); ?>" id="<?php echo $this->get_field_id('profile_image'); ?>" value="<?php echo $instance['profile_image']; ?>" />
            <input type="button" class="select-img" value="Select Image" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('name'); ?>">Name</label><br />
            <input type="text" name="<?php echo $this->get_field_name('name'); ?>" id="<?php echo $this->get_field_id('name'); ?>" value="<?php echo $instance['name']; ?>" class="profile_widget_fields" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('description'); ?>">About Us</label><br />
            <textarea rows="5" name="<?php echo $this->get_field_name('description'); ?>" id="<?php echo $this->get_field_id('description'); ?>" class="profile_widget_fields" ><?php echo $instance['description']; ?></textarea>
        </p>
        <script>
            var image_field;
            jQuery(function ($) {
                $(document).on('click', 'input.select-img', function (evt) {
                    image_field = $(this).siblings('.img');
                    image_preview = $(this).siblings('.selected-img');
                    tb_show('', 'media-upload.php?type=image&TB_iframe=true');
                    return false;
                });
                window.send_to_editor = function (html) {
                    imgurl = $(html).attr('src');
                    image_field.val(imgurl);
                    image_preview.attr('src', imgurl);
                    tb_remove();
                }
            });
        </script>
        <?php
    }

    public function update($new_instance, $old_instance) {
        // This function Updating widget values/data replacing old instances with new instances
        $instance = array();
        $instance['title'] = (!empty($new_instance['title']) ) ? strip_tags($new_instance['title']) : '';
        $instance['profile_image'] = (!empty($new_instance['profile_image']) ) ? strip_tags($new_instance['profile_image']) : '';
        $instance['name'] = (!empty($new_instance['name']) ) ? strip_tags($new_instance['name']) : '';
        $instance['description'] = (!empty($new_instance['description']) ) ? strip_tags($new_instance['description']) : '';
        return $instance;
    }

    public function widget($args, $instance) {
        // basic output just for this example
        echo $args['before_widget'];
        if (!empty($title))
            echo $args['before_title'] . $title . $args['after_title'];
        ?>
        <style>
            .profile_pic { width: 39%; float: left; margin-right: 15px; }
            .profile_pic img { width: 100%; border-radius: 10%; }
        </style>
        <h4 class="widget-title"><?php echo $instance['title']; ?></h4>
        <div class="profile_pic">
            <img src="<?php echo $instance['profile_image']; ?> "/>
        </div>
        <div class="profile_data">
            <p>
                <label><strong>Name : </strong><span><?php echo $instance['name']; ?></span></label>
                <label><strong>About Us : </strong><span><?php echo $instance['description']; ?></span></label>
            </p>
        </div>
        <?php
        echo $args['after_widget'];
    }

}

// end class
// init the widget - to run
add_action('widgets_init', create_function('', 'return register_widget("Profile_Widget");'));

// queue up the necessary js
function hrw_enqueue() {
    wp_enqueue_style('thickbox');
    wp_enqueue_script('media-upload');
    wp_enqueue_script('thickbox');
    // moved the js to an external file, you may want to change the path
    wp_enqueue_script('hrw', '/wp-content/plugins/profile-widget/script.js', null, null, true);
}

add_action('admin_enqueue_scripts', 'hrw_enqueue');

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.