Widget class with custom parameter

What are you talking about?

I can’t be the only one that would love to automate the instantiation of a new widget class e.g.

$WP_Widget_Person = new WP_Widget();

If you are not in this group of people and cannot think why it would be lovely, here are some reasons:

  • You feel hardcore because you are doing some OOP stuff
  • You can create as many widgets as you would like without repeating code e.g
    $WP_Widget_John = new WP_Widget();
    $WP_Widget_Matthew = new WP_Widget();
    $WP_Widget_Luke = new WP_Widget();
  • You don’t have to code each individual widget when you want to make it; granted that plugins will usually do the hard bits for you – but this article is not about taking shortcuts, but rather optimizing your workflow for future projects, code re-usability and ultimately Trimming the Bloat of your site.

But how

Its all good and well to say this, but do we really want to extend WordPress core to do this? And how are we going to get this right?

Well, I think first we need to break it down into some simple Object Orientated principles – (looking at how WordPress core widget classes work):

  1. You create an abstract parent class (which in our case is WP_Widget)
  2. You extend this class by creating a child class:
    BS_Custom_Widget extends WP_Widget
  3. You call the parent constructor method within your own constructor method:
     function __construct() { parent::__construct(false, "John", array( 'description' => "This is a person widget" )); }

    Obviously I am simplifying this for the sake of example so I am leaving out Internationalization.

Okay, lets put the breaks on here

At this point we see that we can in fact hook some of our own parameters in here. Wouldn’t it be great if we could do something like this.

 function __construct($name , $description) { parent::__construct(false, $name, array( 'description' => $description )); }

Now if it was possible to declare our own widgets we could send names, descriptions, and any other object specific information to the WP_Widget core class e.g.

$WP_Widget_Kanye = new WP_Widget('Kanye' , 'This is a male widget');
$WP_Widget_Kim = new WP_Widget('Kim' , 'This is a female widget');

Awesome right!?

But how do we get this right?

If you weren’t already confused, here is some language that will definitely tip you over the edge

The WP_Widget class is not directly responsible for registering widgets, this privilege has been granted to the WP_Widget_Factory class, which can be found under wp-includes/widgets.php

There is an array in this class that holds all of the current widgets as well as registers new ones.

We need to access this array and add our own widget here. What we will need to do is to extend this class ourselves (like we did with the WP_Widget class) and then write our own register() method, which will access and update the $widgets array.

class WP_Widget_Custom_Factory extends WP_Widget_Factory {
function register($widget_class , $widget_args) {
$this->widgets[$widget_class] = new BS_Custom_Widget($name , $description);

Then in our

BS_Custom_Widget extends WP_Widget

constructor – our parameters will hook into the widget class:

All we need to do now is instantiate our extension of the  WP_Widget_Factory class and call our new register method.

 $WP_Custom_Widget = new WP_Widget_Custom_Factory();
$WP_Custom_Widget->register('BS_Church_Widget' , $widget_args);

I would love to see something like this becoming a core part of WordPress in the future, but for now this long winded approach is the best that I can find.

If anyone is confused or has any suggestions, feel free to comment.



Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s