Custom page templates not working

Despite having read the Theme Wrapped Explained article, I’m unable to get any of my custom page templates working aside from front_page.php.

I’ve scoured forums and blogs about the proper way to do this, but have found discrepancies.

So I’m asking…if I’m using the current version of Roots…if I have a page called “products” - how do I go about creating a custom page template for it, while still utilizing the benefits of DRY/the theme wrapper? I suppose I could always create a page template the ole’ fashioned way, but that basically defeats the purpose of using the Roots theme.

Any insights would be greatly appreciated.

It would be helpful to know what discrepancies you have found.

For a page called products;

  1. Copy and rename page.php to page-products.php.
  2. Copy and rename base.php to base-page-products.php, but only if you need to heavily customise the base markup.

The wrapper follows the traditional WordPress hierarchy, but cuts out the need for calls to the header, footer and sidebar markup within the page template.

The most common solution I’ve come across is the following:

  1. duplicate page.php and name it page-products.php
  2. duplicate content-page.php and name it content-page-products.php
  3. change the template part reference in page-products.php to point to the file referenced in step 2, content-page-products.php
  4. customize content-page-products.php as needed

However, upon doing this, nothing changes when I save the files, run grunt, or re-save permalinks. I haven’t come across any resources that suggest creating a duplicate of base.php. Doing so would more or less go against the DRY principle, which is to avoid repetition of get_header(), get_footer(), etc.

The theme wrapper has nothing to do with the files in the templates folder. The wrapper simply allows you to reuse the base markup and removes the need to call get_header, get_sidebar and get_footer in every template.

Most of the time you only need a new base.php is when you significantly modify the base markup i.e the header, footer and/or sidebar (less so the latter). This was my caveat to my second step above.

However, you are wanting to customise the content markup, not the base markup, so the wrapper is irrelevant and the steps you outlined are correct. Running grunt is unnecessary in this context, likewise for re-saving permalinks.

You may want to check your page slug is products (if you had a previous version of the products page it could be saved as products-2, or check if a custom template has been set in the dashboard. You can also use my free plugin to check that page-products.php is being loaded correctly; I’m guessing it’s not.

It’s encouraged but you don’t strictly need 3 and 4 of the steps you outlined, but the reason why we put ‘partials’ in the templates folder is so they can be reused elsewhere. But as I suggested before, making that work has nothing to do with the wrapper and is just using the default WordPress functions.

I have a custom page set for the homepage, which is front-page.php.

Given your 2-step suggestion, am I correct to say I won’t see an additional page template for Products in the Template dropdown (when editing a page)? So far, I’ve only seen 3 there - Default Template, Custom Template, and Front Page Template.

  • What’s the difference between Default and Custom? Safe to assume child pages are using Default Template by default?
  • Should I be working from a child theme? The Roots walkthrough doesn’t indicate that I should be, but not doing so would make updating to a new version difficult…

What’s the difference between Default and Custom? Safe to assume child pages are using Default Template by default?

Default Template is the default WordPress page template page.php

Custom corresponds to the sample template template-custom.php. This is just a placeholder template provided by Roots.

If you’re still unable to make your products page work, you might try something like this in header.php:
Current template: <?php echo get_page_template(); ?>

After a few additional attempts, I cut my losses and downloaded a fresh copy of the Roots theme. This time everything worked as expected - upon creating page-products.php, the Products page was getting that template file.

So let’s say I do this for each of my child pages. Since all page.php really does is get page-header.php and content-page.php, wouldn’t I need to take the same approach with content-page.php (i.e., create a corresponding content-page-products.php)? I’m looking to add HTML markup to specific pages.

If this isn’t the right approach, where should I be placing my HTML?

By the way, thanks a million for your help :smile:

I think you mean “pages with a given template”? Page parent/child is something different.

Yes, that’s one way. You could also just create page-products.php and add php conditionals in base.php and/or content-page.php.

Or, in page.php you could add:

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

Also, for reference.

I like the idea of adding the snippet you provided, as it eliminates a lot of redundancy.

So I tried both a and b (separately):
a) replacing <?php get_template_part('templates/content', 'page'); ?> with <?php get_template_part('templates/content', get_post_type() != 'post' ? get_post_type() : get_post_format() ); ?> and also creating the separate content files (i.e., content-page-products.php)
b) keeping my separate page files (i.e., page-products.php) and also corresponding content files (i.e., content-page-products.php).

I then cleared everything out of content-page-products.php and typed the word “Test”. In neither case was there any sort of change. The separated content files are saved within the /templates directory`, but it doesn’t look like this organization is working.

Did you confirm that page-products.php is the loaded template? <?php echo get_page_template(); ?>

If so, then in page-products.php:
<?php get_template_part('templates/content', 'page-products'); ?>

…will work (assuming the page slug is ‘products’)

If you can’t find the problem, post the content of your content-page-products.php and page-products.php (version b).

Great, this worked!

Since content-page-products.php is grabbed within the while loop found in page-products.php, is the code I use there also part of the loop? Or, if I’m looking to pull in meta content from a plugin, will I need to add another loop inside content-page-products.php?

Yes, content-page-products.php is part of the loop when included from page-products.php.

No, you don’t need another loop inside content-page-products.php to pull in meta content.

Also, since this discussion isn’t Roots-specific, I’d encourage you to checkout and for more details on templates, the loop, post meta, etc.