If you’re creating WordPress themes you surely came across the get_template_part
function at one point or another. It’s one of those hidden gems inside of WordPress that don’t get the attention they deserve. Let’s change that.
The get_template_part
function is essentially a PHP include
or require
, on steroids:
- It already knows where your theme is located and it will look for the requested file in that theme’s directory
- It doesn’t issue a warning or fatal out if the requested file does not exist
- It can search for other suitable files, if the requested one is not found
- It knows about child themes and parent themes
Long story short, the get_template_part
function allows you to break your theme down into smaller templates (or template parts), which can be reused across your other templates.
Although get_template_part
is similar to a PHP include
or require
, you should not use it to include things like your theme options code, sidebars registration, custom widgets, etc. The get_template_part
function should only be used to get template parts.
Let’s start off with some basic examples.
Basic Usage
Suppose we have a theme that has some post navigation elements above the post and below it. Let’s grab that and put it in a navigation.php file instead. Now, whenever we want to render our post navigation, all we would do is:
get_template_part( 'navigation' );
Which will load our navigation.php file if it exists. That’s fairly simple, right? Let’s add a little more spice to that. Since our post navigation goes above and below the post content, let’s add the second argument to get_template_part
:
get_template_part( 'navigation', 'above' ); // post content goes here ... get_template_part( 'navigation', 'below' );
The first call will look for navigation-above.php in our theme folder, and if that doesn’t exist, it will fall back to navigation.php. Similarly, the second call will look for navigation-below.php and fall back to navigation.php.
Pretty slick, eh? But the real power of get_template_part
lies within the child themes model.
Child Themes
If you’re not familiar with the child themes model in WordPress, I strongly recommend you refer to the Codex. In a nutshell, a child theme may override the template files in your parent theme with their own, thus making modifications to the original theme without changing its source code or structure.
The get_template_part
function plays quite an essential role in the child themes concept. Let’s go back to our first example from earlier:
get_template_part( 'navigation' );
As I already mentioned, this will look for a template file called navigation.php. However, if we’re in the child theme context, meaning a child theme is activated, such a call to get_template_part
will look for navigation.php in our child theme first. If navigation.php is not found in our child theme, it will load the one in the parent theme. Makes sense?
Now comes the tricky part:
get_template_part( 'navigation', 'above' );
In a child theme context, this will look for the following templates in the following order:
- navigation-above.php in the child theme
- navigation-above.php in the parent theme
- navigation.php in the child theme
- navigation.php in the parent theme
The order is pretty important and something you should keep in mind.
Given this fallback model, it’s pretty common to use non hard-coded values with get_template_part
in themes. For example:
get_template_part( 'navigation', get_post_type() );
Where get_post_type()
will return the name of the post type that is currently shown, so if we’re on a Post, it’ll attempt to load navigation-post.php and fallback to navigation.php. If we’re on a Page, navigation-page.php and navigation.php. If we’re looking at a custom post type, say a Book, it will look for navigation-book.php and fall back to navigation.php.
A more common use case is post formats, with the post’s content area extracted into a template part of its own, like this:
get_template_part( 'content', get_post_format() );
Which will attempt to include content-gallery.php for gallery post formats, content-quote.php for quote post formats, and so on. If the particular file doesn’t exist, it will fall back to loading content.php. You can see this approach in action in the Twenty Eleven and Twenty Twelve themes.
Even if your theme does not include template files for all available post formats, it’s okay to follow this model, because a child theme might, and if it doesn’t, WordPress will just resort back to content.php.
Under the Hood
The real power of get_template_part
comes from a function called locate_template, which does the whole searching in parent theme and child theme folders, and the reverting to other templates in a stack. The get_template_part
function simply builds an array of templates for locate_template
to look for. Here’s a quick example:
get_template_part( 'one', 'two' );
Creates an array of “one-two.php” and “one.php” (in that specific order) and passes it on to locate_template
, which then loops through that array and looks for the files in the child and parent themes directories. The order is really important here, it’s kind of why file names have priority over their locations (parent theme or child theme) and explains the reason behind the lookup sequence.
It’s also worth noting, that functions such as get_header
, get_sidebar
and get_footer
are very similar to get_template_part
with a sort of hard-coded first argument.
At the time of writing, get_template_part
is located in wp-includes/general-template.php and locate_template
is in wp-includes/template.php.
Well, that’s about it folks! You should now be the master of the get_template_part
voodoo, and now that you’re using it in your themes, you should get approximately 74% more sales. If you have any questions, go flood the comments. Take care!
Thanks for this detailed explanation. As you said, I’ve seen it before but haven’t taken the time to learn how it works but now that I know I can definitely think of use cases where this would be much better than using if/then statements or other alternates.
You’re welcome Zoe, glad you found it useful :)
Is there a benefit to this as opposed to using, say, your functions.php to just write dynamic functions for that purpose? Obviously you could copy template parts across themes, but you can do that with a function too, right?
Josh, sure, you can use pluggable functions in your functions.php file, similar to what Twenty Eleven does with
twentyeleven_content_nav
which can be redefined in your child theme to replace the parent one. You can also make magic happen with an action or filter.I prefer to use
get_template_part
for any template-related content, pluggable functions for ones that return anything but HTML, and actions and filter where I need more sophisticated scenarios. It’s totally up to you, but I find template parts much easier to use than the rest.So it’s more of a preference, than anything. Cool, thanks!
Seems like one compelling reason could be readability of the theme files. If you want to give others a better ability to read your theme and make changes, then it seems like pulling this kind of thing into the theme files might be the way to go. I’d love to hear otherwise, though – this isn’t something I’ve thought much about at all.
Readability and the ease of modification are certainly good points. Thanks for the feedback!
I was mostly thinking about code edits in my reasoning. If I wanted to fix verbiage or change placement of anything in
navigation.php
, I’d have to change that innavigation-above.php
andnavigation-below.php
. It’s a pain, and heaven forbid if you make a copy/paste error.Using functions, you just change it once, and wherever you call it is already changed. Readability didn’t really cross my mind…
That said, I cannot really think of a clean way to mimic the content-{post-format}.php approach by using pluggable functions or actions and filters.
I can’t argue, the if/else statements get a little nuts. And that said, I may start using your categories for functions/templates/actions.
Wow thanks for the explanation. Was using this without understanding but now I do understand.
You’re welcome, glad you found it useful :)
I’ve been meaning to write something like this for ages, but you beat me to it. Even although I know how
get_template_part()
it was nice to see a simple, and easy-to-understand article! :) The race is on! ;)Thanks for the feedback Mark!
This is really great artivle Konstantin. I deffinatelly use this tips my next costumers theme. Have a nice one thanks
Will do sir, thank you!
There’s also a way of using subdirectories for your template parts; check this ticket: http://core.trac.wordpress.org/ticket/15086
Yeah, I’m not sure I like the proposed patches though :) Thanks for stopping by Kirk!
I also would like to gather all template parts in a subdirectory of their own, just like we can now do with page templates.
The reason I say that is for the argument of readability, it surely helps to make the theme *structure* also more readable and when you start adding lots of different template parts, then readability doesn’t necessarily improve.
Just to clarify, you can already do that with:
Though Peter says:
I am sure others have done this but one thing I have been testing out is using this for different blog post templates based on the category the posts are in.
For example, within single.php I have:
Of course, this will only get the first category it returns. For clarity, ‘post’ tells me in my template folder these views are for the post_type of ‘post’. Then, all I need to do is create different templates based the category slug if I need them. So single views now have the options of:
post-news.php
post-events.php
etc…
Hey Randy, that looks pretty neat, though I wouldn’t use something like that outside of a custom project. Thanks for your comment!
I agree, I never would use it for anything other than a custom theme for a client. (All I do is custom projects.) I just got tired of all those conditionals for “if” this category or “that” category. This just seemed to work cleaner.
ps – Sorry if the code came across as spam.
Thanks for this post. I’ve been using reusable template parts in my themes for a while and I really love it. It keeps the main template clear of lots of little stuff (like nav, in your example) and also keeps the functions file free of these same basic content areas. Also it’s a little more clear for template designers who feel comfortable with HTML but are not so comfortable editing PHP. You can shuffle these snippets around easily to change how your pages look.
Adrienne, exactly! Thanks for your comment :)
Awesome! I had no idea that it had fallbacks built into it. And where it locates the file from the parent to the child.
Makes so much sense to just build child themes in the future.
Thanks for this post and all the nice explanations.
When I was building a theme for a customer I started using get_template_part() to organize it in reusable pieces, but then I noticed it won’t work when you define some local variable in the main php file and then you call it on the template part…for this reason I started to use the following
Is it a bad practice?
Hey Luis, thanks for your comment! Indeed, the scope is changed since required is called inside the
load_template
function. It’s not necessarily bad practice to short circuit it, but I’d rather have functions that return values, than variables in the theme scope.Thanks, this is a great explanation Kovshenin :)
Just like Adrienne Adams case above, I ever use get_template_part function to add a sharing capabilities on my theme. All I do is make a list of sharing buttons snipets from it’s official sites wrapped in an ul (more like an HTML) and name it sharing.php, It Works perfectly, and make my work faster.
The change from twentyten to twentyeleven where in twentyten all posts generated from loop.php which have too many conditional tags, that make me never really want to learn WordPress theming at first. But after seeing twentyeleven which using content-(post-type).php it feels a lot cleaner and understandable, good for beginner.
I want to make a new theme for my blog now, I like a starting theme like starkes, but sadly it was based from twentyten, anyone know twentyeleven-based naked theme like starkes?
Thanks for the kind words! If you’re looking for a great starter theme, check out Underscores.