A Complete Guide to Making Your First WordPress Widget

Widgets are a powerful part of WordPress, and they’re a great way to enhance your site’s sidebar. Or your footer. Or your homepage. Or another part of your site that your theme maker thinks would look really good with some widgets.

For the uninitiated, a “widget” is just a WordPress word for a certain type of drag-and-drop build-block area of your site that is made available by a theme. There are tons of different possible widgets, and many built into WordPress. Traditionally, they exist to allow non-developers to easily customize their WordPress site’s sidebar. But at various times, and in various themes, widgets extend far beyond that. Some themes are widget-areas as far as the eye can see, some use widgets in a number of selected and flexible areas, and there are still some old themes you may come across that make no allowances for widgets at all.

A “widget” is just a WordPress word for a certain type of drag-and-drop build-block area of your site that is made available by a theme

We’ll skip the basic tutorial about how you use widgets, because I want to get to the heart of how you make your own. If you’re not familiar though, I’d recommend reading through this page from the WordPress Codex about the basics of the interaction pattern you use with widgets.

Where? Put The Widget In Your Theme? Or a Plugin?

To make your own widget, you’re going to want to use either your theme’s functions.php file, or your own plugin. I’m a big opponent of “theme creep”, but I actually think that widgets straddle that hard-to-call borderland between a presentational-only element that’s fine in a theme, and a bit of completely independent functionality that clearly should be in a plugin.

A good way to decide which is better for your case is to ask yourself “Will I want to have this widget if I change themes?”

A good way to decide which is better for your case is to ask yourself “Will I want to have this widget if I change themes?” The answer to that will be “no” if it’s truly a presentation-only widget, and then you should go ahead and feel comfortable using functions.php. If the answer to that is a “yes”, then I’d recommend making it a plugin.

One reason people don’t make a plugin when they should is that it seems daunting, but it doesn’t need to be. Once you understand what makes a plugin a plugin, you can make them easier than a peanut butter and jelly sandwich. (I know people say “easy as pie,” but I find it rather hard to make a good pie.) Here’s a quick tutorial that explains what a WordPress plugin is and how to make your first. If you follow that you should have a working plugin in under ten minutes.

WordPress Widgets are a Specific Kind of WordPress Object

One of the most daunting parts of making a WordPress widget for many new programmers is that they’re this crazy object-oriented thing that many novice programmers struggle to understand. Object orientation is still not pervasive in WordPress, so someone can get quite a bit done without ever using it. But in the case of widgets, if it’s possible to do it without object-orientation I’d strongly discourage it.

I’ve written an introduction to what you need to know about object orientation to be effective with WordPress, and if you’re new to the whole arena I’d recommend checking it out first. If you have, then you’re ready to know one concept I left out that article that you really should know about: inheritance of objects. Let’s dump a bit of code to start:

class First_WordPress_Widget extends WP_Widget {}

If you feel completely comfortable with that, skip to the next section. If not, you may want to read my explanation extending the object-oriented concepts of WordPress. The summary of what you should understand about inheritance before we go on is as follows:

  • It serves one useful purpose: it allows for more code reuse and replacability of components.
  • Because of it, we get to take advantage of all the cool features that the WordPress core team has built into the WP_Widget class for us.

A Simple Example: An Unalterable Widget

In addition to getting properties and behaviors from the inheritance, we need to add some of our own methods to our WP_Widget-extending class. There are things that make our widget and class unique among all the WP_Widgets.

For a really dead-simple (and kind of useless) widget, you just need to implement one method on your class that WordPress will need. That is widget(), which WordPress calls and will expect to have output. So you’ll need an echo in PHP. And it really can be as simple as that:

<?php 

class First_WordPress_Widget extends WP_Widget {
    public function widget( $args, $instance ) {
        echo 'First WordPress Widget! Yay!';
    }
}

That is a totally valid, and kind of useless widget. You’ll be able to drag it onto a sidebar are see it appear. Well, nearly…

Don’t Forget To Tell WordPress to Look For Your Widget

Extending the WP_Widget class and making a widget() method in it is 90% of the way there, but you can’t forget the crucial step of telling WordPress about your widget. This is done with two different steps. The first is to tell WordPress about your extending of the WP_Widget class, like so:

add_action( 'widgets_init', 'first_wp_widget');
function first_wp_widget(){
     register_widget( 'First_WordPress_Widget' );
}

If you’ve been around WordPress a while, this “hooking” may look pretty familiar to you. The executive summary is that you’re telling WordPress that when it reaches the widgets_init part of its process, it should let our widget, registered by our first_wp_widget() worker function, into the process. If you want to know and understand more about hooks in WordPress, check out this older article of mine, which is still 100% up-to-date on the topic of hooks and filters in WordPress.

If you get that far, you’ll be able to drag around your widget, but you’ll have another issue — your widget doesn’t have a very clear or useful label inside the WordPress customization screens. That’s where the second necessary step comes in: making a constructor for your widget. PHP Constructors are a another topic I covered in my deeper-dive into OO PHP for WordPress, but the summary is that every time PHP builds a WP_Widget, it’ll run what’s in the __construct() method, and WordPress prefers that you give it some useful data there.

Screen Shot 2014-07-28 at 10.35.31 PMAs the Codex example shows, you’ll actually want to do a bit of heady maneuver here. Let me dump the code, and then I’ll explain. This is literally as-is from the Codex page:

parent::__construct(
            'foo_widget', // Base ID
            __('Widget Title', 'text_domain'), // Name
            array( 'description' => __( 'A Foo Widget', 'text_domain' ), ) // Args
);

Essentially, this is potentially confusing but kind of simple. The construction method of WP_Widget requires some paramaters, and we’re providing them for our widget by calling into the the WP_Widget “parent” class when our constructor is called. That’s what the parent::__construct does.  This way it’s as if the user of our widget initiated it perfectly, but we’ve done it for them. If you don’t get why or how, you can just know to do it. It’s honestly pretty obscure and not a thing you should commonly do outside of situation like this.

The constructor of WP_Widget takes three arguments: the ID of your widget — a unique string to identify it, a name value (in this case screened for localization), and an array which can (and in the case does, again with localization __() magic) define the description. The title and description are what show up to users on the dashboard as they’re dragging it around, as shown at right.

Allow People to Set Data on Our WordPress Widget

The final thing you may want to do with your widget is to collect and save data so that users are able to not only drag your widget around on their various widget areas, but also customize their look with a simple form. This is done with two different methods that are built into the WP_Widget class: form and update.

Given how long we’ve been going, and how much the details of these two methods could be explored, I’ll constrain myself to a summary. What the form method should do is output a valid collection of HTML that your widget should give your users. It should take the valid information currently saved in the widget and fill it in as well. What your update method should do is take set of data that a user may have submitted and make sure that it has no dangerous or problematic values in it before WordPress saves it for your automatically in the background.

Going Beyond our Basic Widget

What our widget does here isn’t much, but I’m hoping it gives you a basis to understand the dynamics of WordPress widgets and be productive with them. There’s a lot of complicated concepts for a relative beginner in the way WordPress widget works, so if you’re still swimming I’d recommending digging deep into some of our linked pieces that hope to flesh out the conceptual gaps. And there’s always the comments, where we’ll do our best to answer your questions.

Image credit: cjsorg


5 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Day 2 of testing my plugin | by Blogger Mom
February 27, 2015 1:52 pm

[…] wpshout.com A Complete Guide to Making Your First WordPress Widget […]

All You Need to Know About Making Widget Areas in WordPress Themes | WPShout.com
November 11, 2014 2:44 pm

[…] user can fiddle with widgets, nor how to make them for yourself (we did cover that one before, with the basics and a guide to user-editable ones). Nope, here we’ll explain how you make areas appear in […]

Creating Dynamic, User-Editable Widgets | WPShout.com
October 21, 2014 4:50 pm

[…] we’re continuing David’s discussion of widgets from a few weeks ago. In his post, David covered how to make a static widget: one that displays, say, a predefined block of images and text, or […]

Mario M
August 8, 2014 5:49 pm

Thanks David, great write up. Will you be publishing any info on further using the form and update methods?

Fred Meyer
October 30, 2014 2:03 pm
Reply to  Mario M

Thanks! Yes, we followed up on the topic here.