As far as rapid prototypes and WordPress are concerned, we’ve done two things thus far:
At this point, we’ve done enough work to warrant beginning to refactor our code. That is, we’re going to start converting the prototype to code. But this is something that’s going to need to be done in two phases.
First, we’re going to simply introduce classes that represent the diagrams from the previous post and that encapsulate the responsibility of each project.
After that, we’ll look at organizing the code into namespaces and packages. Before we can do that though, we need to make sure the code is object-oriented and remains functional. So that’s what’s going to happen in this post.
Prototype To Code
If you’ve been reading the previous posts, note that I’m planning to follow the organization I sketched out in the last post. You don’t have to follow this particular design, of course.
A Word About Source Control
If you’re using source control, this is where I recommend creating a branch off of the master branch (if you’re using Git) so that you can do your work without harshing the stable version of the code.
This is a bit beyond the scope of the series, so if you’re not using source control, no worries. If you are, I’m opting to go with develop as the name of this branch. I’ll merge it back into master once I’m sure it’s functional.
As per the work sketched yesterday, I’m going to create two classes:
- the meta box class,
- the meta box display class.
There will be some code reuse from what we’ve already seen as you’ll see in the following code.
First, our meta box:
And next, our display:
That that in the meta box code, in the meta box code we’re explicitly instantiating the display so that we can call it’s display method when needed.
Another alternative would be to instantiate the two objects separately and then inject the display into the meta box via constructor injection or something similar. This would need to be done in a third-party class.
The advantages of this come from de-coupling the two classes a bit more. Perhaps we’ll review how to do this in the next post.
After that, we need to go ahead and define the class that’s responsible for displaying messages within the context of the Meta Box Display. This is what we’ll call the Post Messenger:
Notice here that the Post Messenger also references the Post Query. This is the class where communication to the database happens. I’ve also included a few helper functions to make the view code a bit simpler as we’ll see momentarily.
And that’s it for the core classes. Of course, we still need to talk about the views.
The views are responsible for rendering the HTML in the context of the meta box. I do not like writing HTML within the context of PHP (nor so I like mixing PHP in the context of HTML, but this is inevitable in this project).
There are some great templating projects to make this easier, but I digress. Anyway, you’ll notice that in the post-list.php file, there are references to helper functions in the Post Query class. This is to make sure I’m not exposing too many properties and violating the Law of Demeter.
Let’s take a look at that file first since it’s the most complicated:
It looks like that standard WordPress code, but remember that since this file is called within the Post Messenger, it’s going to refer to the query as the query that’s wrapped by that class.
The last two files are fairly straight forward. One of them provides a description:
The other provides a message when there are no posts:
Other than that, it the basic functionality is done.
Bootstrapping The Plugin
The last thing we need to do is start the plugin. To do this, we alter the code in the main plugin file so that it looks like this:
That will hook into WordPress, instantiate our plugin, and then set it into motion. When you run it within your installation of WordPress, it should look exactly like it did during the first version.
The only difference is that we now have things organized in classes rather than individual functions.
First, there are opportunities for refactoring here that would reduce decoupling even further (such as different types of dependency injection, etc.) but the purpose of this series isn’t to cover that.
Instead, it’s to take the idea of seeing plugins written by many procedural functions and then break them into more conceptual classes that encapsulate their responsibilities.
Secondly, if you review the source code in the repository for this version of the project, you’ll see that I also introduced composer.json. This is so that I can take advantage of PHP CodeSniffer and the WordPress Coding Standards when writing code.
In the last part of the series, we’ll go through namespacing and reorganize the files. If time permits, we’ll include an autoloader so that we don’t have to manually include files at the top of our plugin file.
Finally, I’ve merged this code into master and tagged it as 0.2.1 (as I had to make a small hotfix) since it’s still very much a work in progress.