Best practice for creating page templates?

Sorry, I don’t think this is entirely Sage specific, but I’m wondering what is considered best practice for creating page templates or, rather, I’m wondering if there’s a better way than the way I am currently doing it.

Assume I want to make a custom template for a page called contact.

Let’s say I started by making a page template called page-contact.php so that WordPress grabs it and uses it for the contact page. I do this by duplicating page.php and renaming it to page-contact.php

In this template I swap out:

get_template_part('templates/content', 'page');

with:

get_template_part('templates/content', 'page-contact');

Then, usually, in /templates I duplicate content-page.php and rename it to content-page-contact.php. In this template I add my custom markup.

With this approach I end up with:

page.php
page-contact.php
-content-page.php
-content-page-contact.php

Then, for each additional page template I need to add, I duplicate this process.

If I have ten different page templates I end up with 20 new files - with 10 of those files having nearly identical markup - the only difference being which page template is called.

Alternately, to get rid of some of this redundancy. I could run a conditional check in page.php -

if(is_page('contact')) { get_template_part( 'templates/content', 'page-contact' ); } else { get_template_part( 'templates/content', 'page' ); }

This is pretty easy and helps to keep the root directory tidy. I just add any new templates into the conditional check as needed.

I’ve read this post, and another similar one.

What I’m wondering is -

How do you set up new page templates?

Is there a way to do this that is better than the conditional check?

Something similar to:

get_template_part('templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format() );

But that maybe checks for the page slug and, if the corresponding template file, ie. content-page-$slug, does not exist then it falls back to content-page as a default?

Does this make sense?

I’m going to poke around and see if I can come up with something, but thanks in advance for any insight in the meantime.

:slight_smile:

Couldn’t you use the global post and $post->post_name ?

There is no point in do the if/else when get_template_part already supports fallbacks.

global $post;
get_template_part('templates/content-page', $post->post_name);
4 Likes

Perfect, exactly! Thanks guys!

This is excellent and I wonder if it should be the default code for page.php seeing as something similar is done with single.php.

I know when I first started using Sage, seeing get_template_part('templates/content-single', get_post_type()); in single.php taught me a lot about how the templates directory was intended to be used. I realized I didn’t need a separate single.php for every CPT and my code base was kept DRYer as a result.

I think the same lesson could be taught for pages by incorporating $post->post_name into page.php.