Theme wrappers sans spanning

Last night at the Buffalo WordPress Meetup I did a little talk about theme wrappers. I briefly alluded to the dangers of tag spanning but didn’t follow up on it, and when I live-converted a theme to use theme wrappers I didn’t convert it to the format I typically use that repurposes header.php and footer.php to help prevent tag spanning. I thought I’d go over it here to help clear that up! Read More »

Even better DRY for WordPress

So I posted a week or so ago about DRY themes for WordPress. Turns out, this has been done already (I thought it might have been), and in an even more awesome way that avoids my conditional-filled logic statements.

Check out scribu’s Theme Wrappers, the most brilliant handling of this issue yet.

With a little bit of extra code in your functions.php file (or in a plugin–after a little more testing I’ll probably incorporate this into the rach5-helper) you have a perfect setup that lets you define a base php file (wrapper.php in his example, but I prefer base.php) and use WordPress standard template names to fill in the gaps, saving you time and energy and keeping you from needing to maintain a 20 line conditional check.

This is an awesome system and absolutely worth checking out if easily maintainable themes is something that matters to you!

DRY WordPress Themes

I’ve been working out a new process for developing WordPress themes and I wanted to share it here before I take it over to the Van Patten Media blog. I’d love to get feedback and tweak it as much as possible!

I’ve been developing WordPress themes for a lot of years–almost as long as I’ve been doing professional web development. One of the biggest problems I’ve run into (especially lately) is writing themes that are easily maintainable.

Sass and Compass have helped in the style sheet department (see my introduction to them) but the WordPress themes themselves still are full of heavily repeated content. What do I mean?

Well, a WordPress theme generally has a few base items:

  • index.php
  • page.php
  • single.php
  • header.php
  • footer.php
  • page-{your-template}.php
  • etc.

“So where’s the problem?” you might ask. “Your header and footer are included in every file, and that solves every problem.” Yes, but I have one requirement that stumps things: I want no tags spanning across files.

What do I mean? Simple: if I open a <div> in one file, I don’t want to close it in another. And with header and footer.php files, that’s exactly the situation you end up in. You probably open up your <html>, <body>, and a number of wrapper <div>s.

That gets unmaintainable quickly when you’re bouncing between multiple projects a day and don’t remember what the third closing div tag lined up with in your footer.php file. So I’ve implemented a new system, visible in the most recent Rach5 commits.

This system forgoes the traditional page.php and single.php templates, and instead makes extensive use of conditionals called from index.php. Now if you are familiar with the WordPress template hierarchy, you know that conditionals in an index file are doing double the work, as WordPress has already tried to find an appropriate file. But by putting the majority of your theme structure in index.php (think of it as your base file) you save yourself a massive amount of work down the line.

You can see in the gist how my files are laid out: header.php now includes the visible header within the tag. And I’m now using a new template part, head.php, to serve the tag. You can see an example of the head.php from Rach5 here (Note: with this method, you could easily include the tag directly in your base file, but I choose not to for maintainability reasons).

Then every time I want to include new content in the “content area” of the site, I have conditionals that determine which file to include. I have two default loop files, loop-page.php and loop-post.php which handle basic loops, and a pg-front.php template part. Calling these conditionals from here causes some extra logic to be executed (duplicating logic that WordPress executed previously, in a way), but caching will make that negligible, and this means I can minimize duplicated template code.

I’ve only loosely sketched out the concept, but you can see it and try it for yourself by downloading the latest Rach5. I’d love to hear what others think!