Separation of Concerns with WordPress Templates

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.

A Vanilla Template File

A Vanilla Template File

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:

  1. Check to see if posts exists,
  2. If posts exists, then start The Loop,
  3. Iterate through each post,
  4. 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.

The Escalated Quickly

“Well that got complicated quickly.”

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 names 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.

Templates Call Functions, Functions Return Data To Render

Templates Call Functions, Functions Return Data To Render

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.

15 Comments

This will easily be the most valuable thing I read all day. The graphic of Ron summed up how I’ve been feeling lately perfectly. Thanks a ton for coming up with this post!

This is a great topic, and really bleeds into many more related issues.

I typically strive for these goals:
1. Minimize the responsibilities of a single template. If you find yourself using conditionals to check for every possible context, you’re probably putting too much on one template. (I’m looking at you index.php)
2. Leave programmer logic out of the templates. This means abstracting to functions where appropriate, and looking for the broad, overlapping purpose of each. Lots of one-offs probably means a bad design.
3. Only use get_template_part when that part is truly re-usable, and will be reused. Otherwise, you’re just making me jump through one more hoop. Otherwise you end up with this: http://m1.behance.net/rendition/modules/3316127/disp/37361f9f92ad3fb63b9e0404ca5eb925.jpg

P.S. This is also why I use Genesis for everything these days. Makes you think abstractly / reusably :)

    Clifton,
    I was thinking the same, about using Genesis. It abstracts things, which over time, has made me use functions for more things, allowing me to reuse code, separate things out, etc.

    Tom, excellent article.

      Pat and Clif — thanks for the comment! I’m not a Genesis developer (though I know some really, really stellar people who are :) and I’ve heard nothing but good things about working with the code, so that’s awesome that these concepts are being pushed elsewhere.

      Naturally, I’d continue to love to them adopted more and more by WordPress developers at large. The problem with saying this, though, is that it implies I’ve got it down perfectly. Which I don’t :).

      Still very much a work in progress.

I was only just thinking about this over the last few days as I am building a page template for a particular purpose…
I originally built it with a whole lot of code in it and have since been doing exactly that, pulling each function out and separating it all… to me it just seemed logical and cleaner – maybe a little bit of OCD ;)

Great article!

Totally with you on this Tom. Though I do have one question concerning this:

Specifically, all of the code that was used to retrieve information from the database is contained in its own file in its on function that you can fall from within the template.

Are you advocating creating one file per function? If so, how/when do you include (or require) those files? I’m just trying to picture what my functions.php file would look like with all the functions I create. Instead, I tend to create a file with several related functions. Something like related-products-meta.php that would contain (you guessed it) any functions required to display related products.

    Instead, I tend to create a file with several related functions. Something like `related-products-meta.php` that would contain (you guessed it) any functions required to display related products.

    Exactly – the idea would be to `include_once` the other files (and the other files should keep all functions that are logically consistent with their purpose).

You and your fancy words being all fancy.

Hi Tom.
Thanks for posting this helpful article!
I think it’s a good step in the right direction towards creating maintainable, extensible and reusable code. Most application frameworks, even those based on PHP, come with a built-in templating engine. WordPress doesn’t, but, at a recent WordCamp, I was introduced to an excellent plugin that includes Twig, PHP-based template language. It does a great job of separating UI markup code from the programming logic.

Take a look here: http://wordpress.org/plugins/timber-library/

Enjoy,

Lyndon

    Hey Lyndon – thanks for sharing this, it looks really cool.

    Definitely bookmarking this to check it out and see if I can’t use it in an upcoming project :).

      Hi Tom,
      Have you perhaps already looked into Timber? I was working with Symfony 2 not long ago and using Twig as well. It’s just great being able to separate template code and all the php logic. I’d love to see an article over this in the future.

      Cheers!

        Hey Fred,

        I’ve got TImber bookmarked as I came across it not too long ago, but I unfortunately have not had the time I’d like to sit down and begin working with it.

        I love that all of these templating engines are popping up for WordPress, though I also would like to see WordPress’ core templating functionality continue to improve over time, as well.

        This isn’t to say I prefer one over the other – I’m actually of the mindset of having quite a few options available – but I think the engines could help drive innovation in core (or vice versa, at some point … just not now ;).

Leave a Reply

Name and email address are required. Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>