How to add a custom page template using a child theme

Page templates are a great way to present your content in a way that differs from the rest of your WordPress site. For example, a page template might present a page without a sidebar, or display your blog posts in a categorized fashion, which then you can assign as your website’s front page. Most themes nowadays provide quite a selection of page templates, but yours might not, or it might not quite do what you need it to do. Let’s see when and how you should create a custom page template.

When to use a Page Template

Page templates, as anything, have their use. If you want to change how your category listings are displayed than, say, your tag listings, then page templates are not the solution. You’re better off modifying/creating category.php and tag.php. In most cases, if two or more posts/pages have something in common and you need to change the way you present them, then the WordPress template hierarchy has you covered. If you need however, to affect some pages or some posts, that are not in some way logically related via a common taxonomy or term, then a WordPress page template is the solution.

For this tutorial, we are going add a page template to the TwentySeventeen theme, that displays pages similarly to plain posts, i.e. the sidebar will appear on the right of the content.

Creating a child theme

Create a folder named twentyseventeen-child and place inside the following two files:

/*
Theme Name: Twenty Seventeen Child
Version: 1.0
Template: twentyseventeen
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/
style.css
<?php
// Place all your custom functions below this line.

add_action( 'wp_enqueue_scripts', 'twentyseventeen_child_scripts' );
function twentyseventeen_child_scripts() {
	wp_enqueue_style( 'twentyseventeen-parent-style', get_template_directory_uri() . '/style.css' );
}
functions.php

If you don’t know what these files are or why are needed, make sure to first read our tutorial on child themes:

Beginner’s guide: Child themes

Creating a page template

Now that our child theme is ready, let’s add a page template file named template-sidebar.php, that includes the necessary information:

<?php
/*
 * Template Name: Page with sidebar
 */
template-sidebar.php

There are two important things to note here.

First, the template’s filename shouldn’t start with page-, or post- or author-, or any other prefix mentioned in the template hierarchy, so we use template- as a known safe prefix.

Second, the comment that we added inside template, is what is needed for WordPress to recognize the file as a page template. The filename and the location don’t really matter (as long as it doesn’t use any of the reserved prefixes mentioned above). You just need to have the Template Name: header followed by a unique name. In fact, let’s edit a page and observe the Page Attributes metabox:

Don’t save the page just yet. If you try to preview it, you’ll just end up with the White Screen of Death. We need to add the required HTML and WordPress template tags so that it’ll work.

Let’s copy the contents of TwentySeventeen’s single.php into our template (sans the the_post_navigation() lines):

<?php
/*
 * Template Name: Page with sidebar
 */

get_header(); ?>

<div class="wrap">
	<div id="primary" class="content-area">
		<main id="main" class="site-main" role="main">

			<?php
			while ( have_posts() ) : the_post();

				get_template_part( 'template-parts/post/content', get_post_format() );

				// If comments are open or we have at least one comment, load up the comment template.
				if ( comments_open() || get_comments_number() ) :
					comments_template();
				endif;

			endwhile; // End of the loop.
			?>

		</main><!-- #main -->
	</div><!-- #primary -->
	<?php get_sidebar(); ?>
</div><!-- .wrap -->

<?php get_footer();
template-sidebar.php

It’s time to see the result! Select the template on a page, update, and view… Voila… aaand that’s not what we expect.

That’s not what we were going for…

After some inspection (which is out of scope of this tutorial), it turns out we need to remove the classes .page-one-column and .page-two-column from the <body> element, and add the class .has-sidebar instead. Go ahead and add the following code in your functions.php file:

add_filter( 'body_class', 'twentyseventeen_child_body_classes', 20 );
function twentyseventeen_child_body_classes( $classes ) {
	if ( is_page_template( 'template-sidebar.php' ) ) {
		if ( is_active_sidebar( 'sidebar-1' ) ) {
			$classes[] = 'has-sidebar';
		}

		$remove = array(
			'page-one-column',
			'page-two-column',
		);

		foreach ( $remove as $class ) {
			$found = array_search( $class, $classes, true );

			if ( false !== $found ) {
				unset( $classes[ $found ] );
			}
		}

	}

	return $classes;
}
functions.php

The highlighted line 3 in the code above is what interests us more for the purpose of this tutorial. Using is_page_template() and passing it a template filename, we can detect if the current request is for a page that has a specific page template assigned. The filename needs to be relative to the theme’s directory, so if the template lived in a folder templates inside the child theme, you’d need to check for ‘templates/template-sidebar.php’ instead.

Go ahead and refresh your page.

You should see your page appear similarly to single posts, including the sidebar (provided there are widgets assigned to it).

Success!

Page templates on posts

Since WordPress 4.7, we can create and assign page template on posts as well. So, perhaps I should really stop calling them “page templates” and start calling them “custom templates” instead. WordPress itself refers to them as “page templates” or just “templates” but it can easily get confusing, considering “templates” is the usual term when referring to a themes template files.

Anyhow, all we need in order to make a template available to other post types, is just another header line in the template file’s top comment:

<?php
/*
 * Template Name: Page with sidebar
 * Template Post Type: page, post
 */
template-sidebar.php

We follow the Template Post Type: header with a list of post type names that we want the template to be available to. We can even remove page from the list, so that it’s only available to posts for example. Of course, in our tutorial this doesn’t make any sense, since we tried to make pages look like posts, so there’s no point in making the template available to posts in the first place. It is however a great feature that you need to be aware of, for your future custom template endeavors!

Conclusion

Creating a custom template is a great way to enhance your WordPress site with custom functionality. Although it can be as complex as you want it to be, actually defining and assigning the custom template is literally a matter of one PHP comment and a few clicks. Combined with a child theme, you will never lose your code when the next version of the parent theme is available.

So, what do you think? Are custom templates easy to define? Do you have any great use-cases the benefit from custom templates? Or perhaps any template-abuse horror stories to share?

Let us know in the comments!

Source files available on GitHub.

Subscribe to our newsletter.

Get fresh WordPress content straight into your inbox. We hate spam more than you do.

Leave a Reply

Your email address will not be published. Required fields are marked *