Custom Templates for Post Types

I have a custom post type called ‘musiccd’. I want to create a custom template for any post with the type ‘musiccd’. I have read the docs, and from what I have read I have to include a ‘base-single-musiccd.php’ file in the roots directory.

I have done that, and just tried to echo ‘Works’, but for some reason it’s not loading the custom template. It’s loading from base.php.

How can I create a custom template for a custom post type?

In addition to base-single-musiccd.php you also need to create a template in the theme root called single-musiccd.php and tell it where to find the content template (usually in templates/). You can use the default single.php as a guide.

Related discussion: https://github.com/roots/roots/issues/1033

I’m a little confused. Why do I need base-single-musiccd.php and single-musiccd.php aswell as a template in templates/?

In single-musiccd.php I have:

<?php get_template_part('templates/content-music-cd'); ?>

In base-single-musiccd.php I have:

<?php get_template_part('templates/head'); ?>
<body <?php body_class(); ?>>
<?php do_action('get_header'); get_template_part('templates/header'); ?>
<?php get_template_part('templates/content-music-cd'); ?>
<?php get_template_part('templates/footer'); ?>
</body>
</html>

In the content-music-cd.php I have the content, custom sidebars etc.

But it appears I am calling <?php get_template_part('templates/content-music-cd'); ?> twice? I’m a little confused, the docs don’t really say much about this at all.

  1. The WordPress template hierarchy selects which template to load, but doesn’t load it. e.g. single-musiccd.php.

  2. The wrapper then checks to see if base-single-musiccd.php exists, and loads it, or the standard base.php if it doesn’t.

  3. The base file then includes the template chosen in step one, at the appropriate time via roots_template_path().

The wrapper’s starting point is determined by the standard template hierarchy, so you need to change that for the wrapper to know which base file to load.

If you change the reference your custom base file to include roots_template_path(); instead of get_template_part('templates/content-music-cd'); then you’ll be fine.

1 Like

Ah. I think I get it now after playing with it a little more.

So basically base-single-musiccd.php contains the main HTML (header, body, footer etc etc), and then single-musiccd.php provides the content. But instead of doing it in single-musiccd.php you tell it where to find the template within the templates file. I’m sure there’s a name for this design pattern.

Correct. You could probably call your content from within single-musiccd.php but Roots calls files from templates/ for page template control and sidebar control so the same principles (DRY) apply to posts.