WordPress Theming – Templates and Subdirectories

Introduction

A previous post on template partials showed how to componentize a theme by breaking out reusable blocks of code into discrete files, and consume them via the get_template_part() function. This has the potential to lead to numerous “extra” files located in the theme root folder beyond the standard theme files. WordPress offers the option to organize template files into subdirectories; this post will continue the example in the previous post and show how to make use of this functionality.

Template Files in Subdirectories

As of version 3.4, released in mid-2012, WordPress quietly gained the ability to scan a theme’s subdirectories for template files; this was initially announced by Andrew Nacin. The scanning is automatic, but to actually consume files within the subdirectories takes just a little work.

As shown previously, basic usage of the get_template_part() function is as follows:

// consume the generalized loop partial
get_template_part('loop');

// consume the author archive-specific loop partial
get_template_part('loop', 'author');

With partials in a subdirectory, the function usage is largely the same. The difference is that the subdirectory name must be prepended to the partial’s general name:

// consume the generalized loop partial
get_template_part('partials/loop');

// consume the author archive-specific loop partial
get_template_part('partials/loop', 'author');

That’s all it takes!

Simple Implementation

The most obvious first step is to create a subdirectory to contain the partials; partials sounds appropriate, so that is what gets used here. Use whichever name seems most appropriate. Then it’s a simple matter to move the current partials – namely, loop.php and loop-author.php – into the subdirectory. The resulting directory and file structure is pictured below.

Partial template filesPartial template files in partials subdirectory

Now that the subdirectory has been created and the partials relocated, there’s some editing to do.

The current theme has a home.php file, which is used for a page set as the posts page in the settings; this file, among other things, has a reference to the loop.php partial, as follows:

get_template_part('loop');

Since loop.php has been moved to the partials subdirectory, this reference will no longer work; there will be no error shown – this is by design – but the file won’t be loaded or executed. The fix is simple: prepend the subdirectory name to the partial’s general name, like this:

get_template_part('partials/loop');

This completes the reference needed for WordPress to do its work. Note that the path is always relative to the theme’s root directory. The above change may need to be made in the following files, depending on which are being used in the theme:

  • archive.php
  • author.php
  • category.php
  • date.php
  • home.php
  • index.php
  • page.php
  • single.php
  • tag.php

Following from the example in the previous post, the author archive gets a special treatment. The author.php, contains, among other things, the following line:

get_template_part('loop', 'author');

Note that the use of the specific name does not change the process used to consume a partial located in a subdirectory; that is, just prepend the subdirectory name to the general partial name:

get_template_part('partials/loop', 'author');

As shown in the previous post, it’s not hard to see how this can be used to establish a generalized output pattern for the loop, and then to create specialized versions of the loop for different contexts, as has been done here for the author archive.

Caveats

This technique only works one directory deep. WordPress does not scan deeper than one level below the theme root. Also, standard theme files (the ones WordPress automatically uses when present) cannot be relocated into a subdirectory. WordPress might see them, but will not use them. In some cases, an error is shown on the page, in other cases nothing is shown at all. These files include:

  • 404.php
  • archive.php
  • attachment.php
  • author.php
  • category.php
  • comments.php
  • date.php
  • front-page.php
  • home.php
  • image.php
  • index.php
  • search.php
  • single.php
  • page.php
  • tag.php

Possible Uses

As has been explained, the loop can be generalized for the common case and specialized for the special cases. All of these fragments can be placed in a single subdirectory to keep the theme root tidy. This can be applied to other types of generalizable content, such as:

  • paging
  • sidebars
  • post formats
  • named page templates
  • content types, e.g. pages and posts

Conclusion

It’s clear that get_template_part() is a very useful function which can modularize themes at the code level. This is further helped by using the subdirectories functionality to organize the resulting partials at the file level. Keeping the theme root as tidy as possible is a good thing; with this technique, only the default files that WordPress expects to see need to be in the theme root.

Other Reading