Template Hierarchy

Every time WordPress serves a page, it has to decide which single PHP file, out of everything in your active theme, should render it. That decision isn't random — it follows a strict, well-documented set of rules called the template hierarchy. Understanding it means you always know exactly which file to create or edit to customize any given type of page.

1. How the Hierarchy Works, in General

For each request, WordPress first figures out what kind of page is being viewed (a single post, a category archive, a search results page, and so on), then looks through your active theme folder for a series of increasingly generic filenames, using the first one it finds. If your theme doesn't provide any of the specific files, WordPress ultimately falls back to the one file every theme is required to have: index.php.

2. Worked Example: Rendering a Single Post

Say a visitor requests a single blog post whose post type is the default post and whose slug is hello-world. WordPress searches for a template in exactly this order, using the first match it finds in your theme:

  1. single-post-hello-world.php — a template for that one specific post, by slug
  2. single-post.php — a template for the post post type generally
  3. single.php — the generic template for any single item of any post type
  4. index.php — the universal fallback every theme must have

Most themes never bother with the slug-specific file and just provide single.php — but the fact that WordPress checks for it first means you can override the display of one particular post without touching anything else, simply by adding that one file.

3. Reference Table: Main Page Types and Their Templates

Page typeTemplate file(s), most specific first
The homepagefront-page.php, then home.php (if "Your homepage displays: a static page" isn't set), then index.php
A single postsingle-{post-type}-{slug}.php, single-{post-type}.php, single.php, index.php
A static pagepage-{slug}.php, page-{id}.php, page.php, index.php
A category/tag/date archivecategory-{slug}.php (or tag/date equivalent), archive.php, index.php
Search resultssearch.php, index.php
404 Not Found404.php, index.php
Note: These are the real WordPress template filenames and fallback rules — install WordPress yourself (see the Installation lesson) to see the hierarchy resolve requests on an actual site; this tutorial site itself doesn't run WordPress.

4. Checking the Current Page Type: The is_*() Conditional Tags

Inside functions.php or directly in a template, you often need to ask "what kind of page am I currently on?" — for example, to add different body classes, load different scripts, or tweak a query. WordPress provides a family of conditional tag functions for exactly this:

FunctionReturns true when...
is_home()The main blog listing page is being shown
is_single()A single post (optionally of a given type or ID) is being viewed
is_page()A static page (optionally a given slug or ID) is being viewed
is_archive()Any archive page (category, tag, date, author, custom taxonomy) is being viewed
<?php
function my_body_classes($classes) {
    if (is_single()) {
        $classes[] = 'single-post-layout';
    } elseif (is_page('contact')) {
        $classes[] = 'contact-page-layout';
    } elseif (is_archive()) {
        $classes[] = 'archive-layout';
    }
    return $classes;
}
add_filter('body_class', 'my_body_classes');

This example hooks into the body_class filter (covered properly in the next lesson) to add a different CSS class depending on the page type, letting you style each layout differently from one shared stylesheet.

5. Why This Matters for Theme Development

Without understanding the hierarchy, developers often resort to giant if/else blocks inside index.php trying to detect the page type manually and change behavior — exactly what the is_*() tags and the hierarchy itself already do for you. Knowing the rules means:

  • You can create page-contact.php and know with certainty it will render only the "Contact" page, with zero risk of affecting other pages.
  • You know exactly which file to open when a client says "the category pages look wrong" (archive.php or a more specific category-*.php).
  • You avoid accidentally editing a file that's actually a fallback for many different page types at once.
Next up: Head into Hooks: Actions & Filters to learn the system (like the pre_get_posts and body_class hooks used above) that lets you extend WordPress everywhere without touching core files.