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?

  • 3
    It's more a preference issue for doing it various ways. There is nothing wrong with your outlined approach. – jdm2112 Mar 16 '16 at 21:34
  • not sure what you are meaning by "preview" in your question when the condition you are referring to is is_single? that is not a preview check. – majick Mar 17 '16 at 13:14

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.

  • you forgot singular.php as fallback for all single posts irregardless the post_type. (since WP 4.3) – iantsch Mar 18 '16 at 14:02
  • post_type archives with a separate WP_Query() are not best practice, due to the extra query on page load. you should not recommend that! Use the built in has_archive flag for CPTs and alter the main query with pre_get_posts filter – iantsch Mar 18 '16 at 14:06
  • @iantsch Right, this isn't a 100% extensive guide to the template hierarchy, just a quick overview of the necessities. Where did I mention using using a WP_Query on an archive page? I mentioned using a WP_Query on a page template as you would need to pull in portfolio items. If you're using archive-{$post-type}.php you wouldn't need to use has_archive as that template will automatically pull in your specific post types posts. – Howdy_McGee Mar 18 '16 at 14:11
  • i know… i just wanted to mention it. but you got the downvote for the static page part. a custom query where none is needed shouldn't be part of an answer. – iantsch Mar 18 '16 at 14:13
  • 1
    @iantsch You keep saying "the right way" but that's conjecture. We just disagree on how to do things - we both see each other's method as inefficient. This may be better as an open discussion in The Loop where multiple people could weigh in. – Howdy_McGee Mar 18 '16 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.