One of the biggest pain points in working with WordPress templates – or, really, any PHP and HTML in general – is how we end up jumping from language to language within the context of a single file.
Obviously, this is unavoidable. I mean, the same thing even happens in other frameworks like .NET and Rails, but one of the things that I’ve seen that continually sets WordPress apart (and I don’t mean that in a good way) is that developers often don’t bother to spend time separating their concerns as it relates to the work being done in any given template.
For those who have been working in WordPress for several years likely know this, and know the frustration this causes.
For those who have recently hopped into WordPress development, there’s a strong chance you’ve likely been overwhelmed with some of what you’ve seen.
It’s a bummer, I know.
But it doesn’t have to be that way.
Separation of Concerns: Templates
When it comes to building templates for WordPress themes, there’s a lot of improvements that we – as developers – could do to make our code more readable, more maintainable, and to generally do a better job of applying tried and true software development techniques to our work.
The Standard Templates
For the most part, the standard templates – that is, files such as `index.php`, `single.php`, `archives.php`, and so on – are relatively fixed. That is to say that they have the same type of code and flow of control regardless of the theme or implementation:
- Check to see if posts exists,
- If posts exists, then start The Loop,
- Iterate through each post,
- Paginate if needed.
And, to be honest, I think that’s great – it makes it really easy for people to get started building things with WordPress relatively quickly.
But when it comes to building more advanced functionality with custom post types, custom taxonomies, multiple queries per page, and so on, then things can get a bit more complicated really fast.
More Advanced Templates
In fact, I think that things can get complicated so fast that by the time you’re done working with the initial version of the template, you not only have several hundred (if not approaching a thousand) lines of code to render your content, you may even have a hard time looking back to pinpoint which part of of the template is doing what.
This is partially the territory that comes with working with languages that allow you to mix function calls and language constructs in the middle of HTML. It’s also partially due to us not being diligent about separating the logical components of our code.
And yes, some frameworks do promote better practices than others. Unfortunately, at least at this point in time, WordPress doesn’t really promote any one right way to build custom template files. But that isn’t to say that there aren’t strides that can’t be taken.
In fact, there are three really easy things that can be done immediately.
1. Write Functions (or Encapsulate Domain Logic)
Sounds easy, right? But if it were that easy, why isn’t this the norm?
Whenever it comes to working with more advanced templates, queries, and rendering the information, it’s really easy to begin abstracting your work so that you can keep your templates clean.
First, encapsulate all of the logic responsible for constructing the query and retrieving the information into a function. In software circles, this is normally called “domain logic” but that’s generally a fancy term for “code that represents the data you’re modeling.”
When it comes to WordPress, this usually has to do with constructing some type of data structure – be it a simple array, or perhaps a more complicated set of objects – from information returned from the database.
I typically do this by creating an `inc` directory in the root of my project directory, and then creating a file name after the logic it encapsulates (such as `acme-taxonomy-queries.php`).
2. Call Functions From Your Templates
Once you’ve abstracted the code into their own PHP files, you can easily call the functions from within your templates.
This will then take what once used to be a massive template file that was a mix of PHP and markup and condense it into something that’s much more readable.
Specifically, all of the code that was used to retrieve information from the database is contained in its own file in its own function that you can call from within the template.
So rather than having to have this huge chunk of PHP responsible for setting arguments, running a query, checking to see if data is returned, and what not, you simply need to call a function, and, say, iterate through the result set.
The function takes care of all of the logic surrounding what should be returned.
3. Document Your Functions
When it comes to having to remember what each part of the template does, it’s much easier to have the functions separated into their own file so that you can provide rich documentation (usually in the form of PHP DocBlocks) that explains what each function does, which it accepts, and what it returns.
This typically does a lot more for maintainers than inline comments, and it’s able to be easily documented by other tools such as phpDocumentor.
Yes, There’s More
Of course, there is always more that can be done, and there is a lot of room for practical examples as it relates to this.
Perhaps in a future post, I’ll cover some other concrete examples for how to do this, but in the meantime, I’d love to see us – as WordPress developers – do a better job of following some of the more basic software development practices like separation concerns if for no other reason than making our own code easier to read and maintain.