WordPress Widgets: Refactoring, Part 8

When it comes to refactoring the WordPress Widget Boilerplate, we’ve done a lot of work to bring the code base up to more object-oriented standard. Further, we’ve introduced a variety of other tools that allow us to bring our code up to more modern standards

Now that we’ve spent time doing that, it’s time to jump back into the code and begin refactoring it in such a way that allows for the use of abstract classes and subscribers (that work as part of the event-driven design pattern).

At the end of the previous post, I wrote:

In the upcoming posts, we’re going to look at how we can implement subscribers for the public-facing side of the site (that is, where the widget content is displayed). And we’ll do the same for the administration area of the site.

So in this post, we’re going to do exactly that. Specifically, we’re going to start with working on a subscriber for the widget and then getting the base widget to display on the administrative side of the site first.

The WordPress Widget Boilerplate: Refactoring, Part 8

The reason that I’m interested in primarily focusing on the administrative-facing side of the site first is that it allows us to:

  • get a handle on how subscribers work,
  • see how the code base will need to be organized,
  • hardcode some information before working with serialization.

Once all of this is in place, we’ll be in a good position to turn our attention to more advanced things. Namely, we’ll be able to introduce subscribers for displaying information in the administration area and subscribers for sanitizing, serializing, retrieving, validating, and displaying data.

But first, let’s do the work necessary to set up a new class, configure the autoloader, and display content in the administrative area of the site.

1. The Abstract Subscriber

Let’s review the abstract subscriber first since this is what all subscribers will implement.

Notice that it has two public functions – the construct that sets the hook and a function for retrieving the hook. It also has an abstract load function which is where any class that extends this class implements its specific functionality.

Recall that because of the way WordPress handles actions and filters, everything is attached to a specific hook (either those that WordPress defines or custom hooks).

2. The WordPress Namespace

Whenever I’m working on functionality that’s tightly coupled to WordPress, I try to make sure that I place it in a WordPress namespace. This indicates to me as well as other developers that whatever resides in this namespace can’t be divorced from the core application.

So within the src directory, create a WordPress directory. This is where the core Widget class will reside along with any other classes will introduce throughout this series.

This means we no longer need the class in the API directory. So make sure to move the class, update its namespace, and remove the directory. I’ll have a screenshot and some code for this a little bit later.

Additionally, recall earlier in the series, we placed the Views directory in the root of the src directory, but now we can move it to the WordPress directory. So go ahead and do that now.

The final result should look something like this:

WordPress Widgets: File Organization

Now we can turn our attention to the code.

3. A Look at the Widget Class

We’re going to simplify the core widget class a bit in this post. It’s going to undo some of the work we’ve done, but we needed that previous work to get us to this point.

For now, we’re focusing on the constructor and the function for retrieving the widget slug. This is what will ultimately allow us to see something in the administrative area of WordPress.

So, first, make sure your Widget class looks like this:

Next, since we’ve moved this file to the WordPress namespace we need to update the autoload section of our Composer configuration file:

Next, we need to introduce a subscriber.

4. Introducing the Widget Subscriber

Whenever I have a core class of some sort, I generally try to create a simple subscriber that instantiates the core class and allows it to do its work.

I do this because WordPress, as mentioned, uses the event-driven design pattern which means everything has to be registered to some type of hook. And I don’t like mixing domain logic with the same class that hooks into WordPress. So I separate them.

And that’s what a subscriber does. It registers itself with WordPress then invokes the class responsible for actually doing the work.

With that said, turn your attention to the Subscriber directory and add a class called WidgetSubscriber. In that class, add the following code:

The constructor will register the class with a specific hook that we’ll review in a moment; then it will use the WordPress API to instantiate our widget (which is what’s happening in the load function).

5. The Bootstrap

Finally, we need to update the bootstrap so that it:

  • registers the WidgetSubscriber with the proper hook,
  • adds the subscriber to the Registry,
  • and starts the plugin (which we’ve been doing).

The bootstrap, after all of this, should look like the following:

Next, you should be able to login to WordPress and activate the plugin.

A Look at the Administrative Area

At this point, there isn’t much to look at, but we’re getting there. First, you should notice that the widget now appears in the area that includes the available widgets:

WordPress Widgets: Available Widgets

And you should also see that when you drag the widget to a widgetized area (or any sidebar) that it has no available options.

WordPress Widgets: Active Widgets

That said, we’re in a good place to continue building on what we have. You can always continue to track the development of the boilerplate on GitHub.

Continuing On

Next, we’ll continue building out functionality for the administrative area of the widget. After that, we’ll turn our attention to the public-facing side of the widget as well as serialization functionality.

You should be able to see how things are beginning to take shape as we begin to separate the logic into its various components. If not, though, don’t worry – there’s plenty more to come.

And the final version of the Boilerplate will, of course, demonstrate all of the principles we’re building on throughout this series of posts.