Understanding the WordPress template hierarchy

I watched a lot of courses about WordPress Development on Udemy. Also I’ve almost finished my “WordPress Development” track on Teamtreehouse, but I can’t understand one simple thing, because one course a little bit contradicts another.

My question is about page.php, content.php and single.php. What is the best practice to use these files?

For example, I need to create a portfolio site. As I understand, I need:

  1. Create page-portfolio.php file that will be my main static page where I will show all the photos.
  2. Create content-portfolio.php file that will be each photo’s preview.
  3. Create single-portfolio.php file that will be a singular post page for my photo.
  4. After that in page-portfolio.php we need to create a loop and execute get_template_part function with content and portfolio as the parameteres. I mean get_template_part( 'content', 'portfolio' ).
  5. In single.php we need to create a loop and execute get_template_part( 'single', get_post_format() ) function. If our custom post has portfolio format, it will be worked perfectly.

Now when we go to our “Portfolio” page, the page-portfolio.php will be shown for us. On this page-portfolio.php we will have a lot of content-portfolio.php items (photos) and when we click on one of them the single-portfolio.php will be shown as a singular post page? Am I right? Is it good practice?

I saw a few themes that use only content-slug.php for the preview and for the singular post page. Underscores uses this practice. They have one content.php for two cases. And in this file they choose what to show to the user with if statement. Something like this:

    if ( is_single() ) {
        the_title( '<h1 class="entry-title">', '</h1>' );
    } else {
        the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
    }

If it’s a preview they show h2 and if it’s a singular post page they show h1. Why don’t they create two separate files for this? Is it good practice to have a preview and a singular post page in one file?

1 Answer
1

A little preface here. I’m going to assume you know nothing of post types or templates since I’m unfamiliar with Underscores or the Teamtreehouse development track. Hopefully the below helps clear things up if not ask further in the comments.

WordPress starts with a few built-in post types that you’re already familiar with:

  • Posts ( post type slug: page )
  • Pages ( post type slug: post )

They use their own templates, usually they go by the following:

  • Posts
    • home.php or index.php is your archive page or list of Posts
    • archive.php is where everything else goes ( archives, categories, tags )
    • single.php is where your single content is going to be.
  • Pages
    • front-page.php to assign a single pages content as your homepage.
    • page.php used for the default template of all pages
    • page-{$slug}.php which is used to target a specific page by their slug.

You could use the above with normal loops to display your content, you don’t necessarily need to use things like get_template_part() which is really just WordPress’s version of PHP include().


Now, what you’re trying to do with Portfolio’s you probably want to build your own Custom Post Type. These Custom Post Types use variations of the above templates:

  • Portfolio ( Your Custom Post Type ) – portfolio will be the slug.
    • archive-{post-type-slug}.php is where your list of portfolio posts will be.
      • archive.php will be the fallback if WordPress can’t find the above template.
      • index.php if there is no archive.php then WordPress will fallback to this template for display.
    • single-{post-type-slug}.php will be your single full portfolio post.
      • single.php will be the fallback if the above template isn’t found.

You would switch out the {post-type-slug} in the above templates with your post type slug so in the end you would have:

  • archive-portfolio.php and single-portfolio.php

Now as far as a static page for your post type you have a ton of options, none of which are right or wrong necessarily.

1) You could create an actual page for it, call it page-portfolio.php but then you would need to run a separate WP_Query() to pull your Portfolio posts because WordPress won’t know to associate that page post type with you portfolio post type. Same issue with a global Page Template but you wouldn’t need to keep track of IDs or Slugs.

2) You could allow the user to assign a page to your post type. Similar to going to the admin panel Settings -> Reading and assigning a Front Page and Blog Page. You could save a page ID into the database and on your archive-{post-type}.php get the content of that page to display it.

I’m sure there are other ways, everybody has their preferred method.


I’m not against using the above method of using template parts to separate your content but I feel it’s overly complicated for beginners when the simplified WordPress templates method is much easier to grasp.

Leave a Comment