One thing that I learned while creating the Ghostbird theme was that is is really important to take advantage of as many templates as possible. I have always said that “If I ever released a theme, it would only have one template file”. This is how Ghostbird was structured for about 90% of the time spent developing it. If you look at version 0.9.1, the only template file you will find is index.php. It was not until a very late stage that I saw the error of my ways and decided to add in other template files like search.php, 404.php and many more.
Once these files were in place I started to look very closely at them to see if there was anything that I could do to make child theming easier for users. I discovered that adding context to all template parts is a very easy thing to do and can allow child themes to modify small sections of a template.
This is one of the first template files that I added. I wanted to be sure to create a unique presentation of search results. I have always been bothered by themes whose search pages look exactly like their blog views. It was one of my goals to make my theme’s search results appear as if they were generated by a search engine. If you want to see what I came up with, you can search my site and check it out.
Here is a very simplified version of a search.php template:
get_header(); get_template_part( 'loop' ); get_sidebar(); get_footer();
It is relatively easy to override this template in a child theme by copying this file from the parent into the child and then modifying the contents.
But what if the user only needs to change something in the loop? What if they want to define a custom sidebar for use only in search views? It kinda seems silly to have to copy the entire template for such a task.
What I discovered is that all of the functions listed above can take a $name parameter.
get_header( $name ); get_template_part( 'loop', $name ); get_sidebar( $name ); get_footer( $name );
For my theme’s search.php I used the string
search for the $name parameter to give the appropriate context that the function is being used in.
get_header( 'search' ); get_template_part( 'loop', 'search' ); get_sidebar( 'search' ); get_footer( 'search' );
Now that the context has been set for each template part function, it is easy to create any of the following files in the child theme to override a small section of the actual template:
Once I discovered this trick, I wanted to apply it to all of my templates!
I’ve read many places before that single.php is the template used to display a single post. While this statement is not technically false, it doesn’t really tell the whole story. This file is actually responsible for displaying a single post of any public post_type (except for pages) that does not already have a designated template file. In other words, single.php is a “fallback” template for just about any query that asks for a single post.
Since single.php can be used to display any post_type, I decided that the $name or context parameter should use the post_type of the post instead of the name of the template file. My single.php looks something like this:
/* * Capture the name of the queried post_type. * * Note: It's a good practice to prefix variables * with something that will not conflict with other * extensions. That is why I used $ghostbird_post_type * instead of $post_type here. */ $ghostbird_post_type = get_post_type(); /* Use the post_type as the context for each template part. */ get_header( $ghostbird_post_type ); get_template_part( 'loop', $ghostbird_post_type ); get_sidebar( $ghostbird_post_type ); get_footer( $ghostbird_post_type );
This setup allows for a great level of flexibility in child themes. Probably the most useful thing that can be done is to create a unique loop template for each registered post_type:
Had the context been given as “single” (like I have seen many themes do) the only solution here would be to create a file named loop-single.php and then write conditional logic within the loop to render a different format depending on the post’s post_type.
Adding context to template parts allows a user to affect only small parts of any given template. Some may argue that setting context in
get_footer() is only helpful is certain situations or “edge cases” and I totally agree! I feel that it important to allow for the greatest flexibility possible for all users. When all is said and done, this may only really help out a very small percentage of your users, but it is very easy to implement and makes extending your theme easier for those who take advantage of this functionality.