So you’ve watched some of the tutorials in the Know the Code, watched my presentations, read some blog posts, and read my tweets. You may notice a trend of how I approach WordPress and PHP coding. Let’s talk about it for a moment.
First of all, know that there are many, many ways to accomplish the same result within software.
The keys are to craft code that is
When you accomplish all three of these keys, you have quality code.Keys to #WordPress coding are: craft code that is maintainable, testable, & reusable. Click To Tweet
How I View Code
I break code down into a single task and then build my classes around that one responsibility. For example, a blog post is comprised of the post content, custom fields (meta), taxonomies, comments, and the next/previous article relationship. Each of these is a separate responsibility. Therefore, I code to model each of these tasks.
Then when it comes time to render it out to the browser, the single.php file pulls it all together as well as calls the views (or template partials). But again the single.php file has its own task as a controller, if you will, routing and managing what tasks need to be accomplished in order to serve the post out to the browser. Therefore, it should only be responsible for that task, i.e. acting as manager or controller. The HTML should be abstracted into views or template partials and then called by the single.php file.
Therefore, I view a single file as having a single responsibility. Everything within the file needs to serve and support the single task and purpose of the file. Always ask yourself: what does this file do? What is it’s purpose? Then look at each of the functions (or if it’s a class, its methods) and make sure they support the purpose. If no, move that function (task) elsewhere into its proper grouping.In #WordPress and #PHP coding, look at a single file as a single responsibility and make sure everything within it supports and serves that goal. Click To Tweet
Don’t Put Everything in functions.php
I see this all the time, where functions.php is this collective assortment of unrelated functions. It becomes a dumping ground for everything, sadly. If we change our thinking to single responsibility, then quickly we realize that each of these functions (tasks) can be (and should be) abstracted out into their own files grouped together with related functions that adhere to the single responsibility of the file itself.
Skinny Functions & Methods – Embrace Refactoring
A function or method should also serve the single responsible philosophy. If there is code within a function that could be used again (re-purposed) or that is being repeated elsewhere, abstract it out into another function or method.
When you look at your code through this type of filtering, you’ll start to see that your functions and methods will shrink in the number of lines of code housed within them.
Remember, you should refactor refactor refactor. It is just a part of your normal workflow. Your goal is as few lines as possible within each function and method, as it’s a measuring stick to the single responsibility approach.
Composer should be the first tool you install within each project. Why?
- There are so many packages available that you can pull into your project to avoid re-inventing the wheel.
- Composer will keep those packages up-to-date. No more having to go out and re-download the latest script or package on GitHub yourself and then manually insert the files into your plugin.
- Autoload. Need I say more. Ok I will. We’ve all seen plugins that are filled with includes and requires. The problem here is two-fold: (1) it does not serve the purpose of the file unless it’s on its own and (2) all those files consume memory. On the memory point, there is no reason to load a file until it is needed. Composer takes care of that for you. When you instantiate a class, the file is loaded. Period.
- Documentation. Composer gives you the utility to document your project.
- It gets you thinking in a “packages” mindset. As you use it more and grow as a developer, you will begin building your code in packages and then merging them together. Some would call these snippets; however, it’s much more than just snippets.
OOP vs. Procedural Coding
WordPress core is a primarily procedural, i.e. uses function-based code versus classes. There are plenty of classes within WordPress; however, a great number of them are extended into individual, standalone implementations versus configured and modular (more on this in a moment).
I come from a different world of high tech where, yes, we had a website as a management, monitoring, reporting, and diagnostic hub; however, the bulk of my work was in making high tech equipment, like robots, serves, instrumentation, etc., function within a production environment. I think a bit differently about coding and approach it from the stance of objects.
For example, let’s take your computer. I’ve designed and coded machines that made computers. Imagine a robot that picks up, inserts, and then solders each of the circuit components on the motherboard. Imagine what it takes to tell this machine to move itself from the pick up point (some of which were on a moving conveyance system requiring vision-guidance to locate) through this path at this trajectory to insertion point, move its end effector to select the next tool, and then do the soldering tasks. Yes, it seems overwhelming, but rest assured, it is not.
All code can be broken down into modules (packages) and down into single tasked (responsible) elements within that module. You then piece together the single tasks (classes) to get the module to do what you want and then piece together the modules you want to get the robot to do what it needs to do. Therefore, everything comes down to that single task, single responsibility of the class.All code can be broken down into modules (packages) and down into single tasked (responsible) elements within that module. Click To Tweet
I write code in Object-Oriented Programming techniques (OOP) because objects make sense to me. A slider has properties like number of sliders, speed, direction, etc. It also does stuff, like slide, pause, auto play, etc. Meta is the same and so are posts and so on. Breaking down your code and thinking about the website into elements helps you to see the objects.
I like how classes encapsulate and abstract away functionality within the black box, exposing only what it wants the rest of the world to see in order to interact with it. I like how it holds state, its own state without having to cache or hit the database again. I like how it drives me to write code that follows all the principles we are discussing here. I like how when I need to pull functionality together for a particular page, I can just instantiate the objects I need and all of its functionality and goodies come along for the ride.
I’ve seen a lot of conversation about procedural being better for themes. I use a combination of OOP and procedural, where the class structures are found in my centralize customization plugin. The rest of the theme is then procedural, although I have coded themes in OOP too.
Here’s a simple truth: it doesn’t matter whether you code in OOP, functional, or procedural. Nope, don’t let anyone else tell you that one programming paradigm is better than another. Again I tend to think in objects. But you can accomplish clean, modular, DRY code in procedural too. Want to hear me talk about this point in more detail? Head over to Know the Code and watch the free video: Procedural, functional, or OOP?
As you watch the videos and look at the code, you start to see a pattern of reuse via configuration. I am an advocate of configuration architecture. I’m believe in removing hard-coded uniqueness out of the code and placing it into a configuration file. This practice makes the code portable and reusable, as it is not tied to a specific implementation. Rather, you just go to the configuration file and make your changes there for the new project or implementation. No more having to go through the code and change text, parameters, or whatever within code. This technique will save you so much time, it’s ridiculous.
I’ll be writing much more on the configuration architecture in this blog.
Separation of Concerns – Don’t mix languages within a file
The code that is compiling the task and doing work (business logic) should have its own class and file. The code that renders out to the browser, i.e. has the HTML in it, should be housed within a Views or Templates folder.#WordPress: #HTML goes into view files and not convoluted in with the PHP code. Click To Tweet
OK, yes, there will be PHP within the HTML file as we need to pass variables to set the link, data attributes, content, and so on. But that’s OK, as the Views’ purpose in life is to render out the presentation of the data.
This philosophy applies to everything, although there may be a few exceptions. For example, if you look on GitHub, you’ll see how I’ve pulled the HTML out of the shortcode class and am instead calling a view file. Notice how the view file is configurable, as this is part of the configuration architecture.
Want to watch me explain this concept further? Then watch this free video: Quality Code Tip: Views are for HTML – Not Your Business Logic.
Themes are for Presentation. Plugins are for functionality & features
Stop for a moment and re-read that heading. Commit it to memory. Themes are for presentation only. That’s it. It sets how the page is put together, what’s on it, and the styling for it. Your clients will go through various different themes over the years. If you place functionality and features within the theme, when they switch to a different theme, poof that functionality is gone.
Extended features and functionality, such as meta boxes, shortcodes, widgets, custom post types, custom taxonomies, custom databases, etc. all go into a plugin.
You have successfully achieved Separation of Concerns and Single Responsibility when you embrace this simple concept.In #WordPress, themes are for Presentation. Plugins are for functionality & features. Pass it on. Click To Tweet
Test. Test. Test. Period.
That’s it. Just test. I practice Test-Driven Development (TDD), where I write a test, which fails, and then write the code for it. This approach serves the following in your craft:
- Tests your code in small increments as you build it.
- Makes sure your code complies with the Keys of Testable Code.
- It will help to drive you towards streamlined, modular code just by its nature and process flow.
- When you make changes, it makes sure that it didn’t break something else within your code.
- Delivers a more stable product.
Just remember that testing can be flawed as you can write code that just makes PHPUnit turn green versus really solving the problem. Also you need to test it in various failure modes of what the user could do to get the full advantage of testing.
.wrap it up
That is an introduction into how I approach code and what I hope to teach you. There will be much more to come.