Modular Themes, Part 2: Theme Organization

April 2010

Modular templates provide us with a new way to organize our themes. In this post, we’ll discuss how separating theme structure from theme content reduces repetitive code and makes theme code easier to follow.

The concepts are based on this belief:

When you edit theme content, you shouldn’t have to copy your structure; when you edit theme structure, you shouldn’t have to edit ten files.

These concepts are best conveyed through example, so we’ll take a look at how get_template_module() can benefit the theme structure in Twenty Ten. However, these concepts (and this example) can apply to any theme.

A note, before we get started:
This is part 2 in a series about Modular Themes.
You should probably take a look at part 1.

Repetitive Code, Revisited

The two glaring examples of repetitive code are the loop and page structure. We’ve already addressed the loop, but things like get_header() and <div class="container"> show up in almost every file. In addition, we often see html elements broken across files—definitely not poetic code. You know it’s bad when best practice is to write </div><!--#container--> because you’d have no idea which <div> you were closing otherwise.

The initial thought would be to encapsulate the opening and closing structure in two template parts, but the workings of get_template_module() suggest an even smoother practice. Currently, nearly all changes between theme pages have to do with the presentation of the content on the page, not the header, footer, or sidebars. What if, instead of repeating structure code on every page, we made a content module?

Our Example: Twenty Ten

Ladies and gentlemen, get your (hypothetical) themes ready. I’ll be using Twenty Ten to illustrate. I’ll refer to several of the html elements (such as #header) within the examples, but they should translate easily for any theme. Here’s a look at Twenty Ten’s structure, and how it’s broken across files:

<!--BEGIN HEADER.PHP-->
<html>
<head>
	<!--title, etc go here-->
</head>
<body>
<div id="wrapper" class="hfeed">
	<div id="header">
		<!--header contents go here-->
	</div>
<!--END HEADER.PHP-->

<!--BEGIN INDEX.PHP-->
	<div id="main">
		<div id="container">
			<div id="content">
				<!--page contents go here-->
			</div>
		</div>
		<!--sidebar goes here-->
	</div>
<!--END INDEX.PHP-->

<!--BEGIN FOOTER.PHP-->
	<div id="footer">
		<!--footer contents go here-->
	</div>
</div>
</body>
</html>
<!--END FOOTER.PHP-->

Creating a Content Module

To isolate our structural code, we’ll begin by creating a content module:

So Twenty Ten’s new index.php would look something like this:

<?php get_header(); ?>
	<div id="container">
		<div id="content">
			<?php get_template_module('content');?>
		</div><!-- #content -->
	</div><!-- #container -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

This is now the only file where we’ll find the page structure. Want to change it for a specific page? Add a new file (say, category.php) and edit to your heart’s content.

A Step Further

While we’re no longer repeating structure, we’re still splitting HTML elements across files—namely header.php and footer.php. The header file is a curious beast; it includes both the head element, and the actual page header, which itself is comprised of a mixture of structure (i.e. <body>) and content (i.e. #header, logos, menus, etc.). These two are grouped together as a result of our current system because repeating the page header over and over is considered a form of torture.

Now that index.php is readable (and short!), it makes sense to separate the two parts of header.php. We’ll use header.php for only the head element (if I had my druthers, I’d rename header.php to head.php).

Creating a Header Module

The footer is similar to the header—it’s part stucture, part content. We’ll do almost the same thing:

The Results: Cross-file HTML tags? Only one!

That’s right, it’s the html tag itself. Let’s take a look at Twenty Ten’s new index.php:

<?php get_header(); ?>

<body <?php body_class(); ?>>
<div id="wrapper" class="hfeed">

	<div id="header">
		<?php get_template_module('header'); ?>
	</div><!-- #header -->

	<div id="main">
		<div id="container">

			<div id="content">
				<?php get_template_module('content');?>
			</div><!-- #content -->

		</div><!-- #container -->
		<?php get_sidebar(); ?>
	</div><!-- #main -->

	<div id="footer">
		<?php get_template_module('footer'); ?>
	</div><!-- #footer -->

</div><!-- #wrapper -->
<?php wp_footer(); ?>
</body>
</html>

It’s a little longer than before, but now all of the theme structure is located in the same file. If you look up at the overview of Twenty Ten’s structure, you’ll notice that only the opening html tag and head element are missing. Now, header.php contains the entire head element, while index.php contains the entire body element.

Let’s run down where our code is now located:

Wrapping Up

More generally, this development pattern dedicates the root template hierarchy to theme structure, and the content, header, and footer directories to theme content. Since all folders apply the template hierarchy, themes become incredibly extensible. Code becomes much easier to pinpoint and customize, which is especially helpful when creating a child theme.

It’s important to note that this development pattern does not rid us of repeated code—only a massive file with lots of conditionals can do that. Instead, it attempts to reduce repeated code by separating content from structure. As I wrote earlier: When you edit theme content, you shouldn’t have to copy your structure; when you edit theme structure, you shouldn’t have to edit ten files.

Want to download this post’s example? Download Modular Twenty Ten.

A Few Extra Thoughts

Shortcut functions: Like this development pattern? We could propose shortcut functions to establish a naming convention: get_content_module(), get_header_module(), get_footer_module() could load modules from the content, header, and footer directories, respectively. Note that these are not part of the current patch.

Performance: I’m sure some of you are wondering about the performance of get_template_module() and how it affects load speeds. From my tests, it doesn’t.

The function name: I am by no means set on the name get_template_module; I just needed something to work with! Ptah Dunbar suggested get_template_file, which is likely a better fit. Any other ideas?

On sidebars: Some of you may be asking why I shied away from modularizing sidebars (in fact, if it helps a theme, I’m all for it). Here’s the issue: get_sidebar() has an optional parameter that acts like get_template_part()‘s optional parameter. In cases where get_sidebar('optional') were called, you’d have to write the following:

if( ! get_template_module('sidebar-optional') )
	get_template_module('sidebar');

Of course, that could easily be encapsulated in a function get_sidebar_module().

On the <html> element: I realize that I could have had zero cross-file tags if I moved the opening html tag into index.php, but I think the DOCTYPE declaration is a natural companion to the head element.

The <head> element could be module: Yep, it could! If your theme’s head could benefit by becoming a module (read: “has a lot of template conditionals”) go for it.

If you’ve made it this far, thank you for reading! I’d love to know what you think.

Modular Themes:
Trac Ticket | Part 1: Why? | Part 2: Theme Organization | Download | Performance