Subscribe to Our Mailing List and Stay Up-to-Date! Subscribe

WordPress Theme Template Hierarchy Explained with Examples

WordPress template hierarchy determines which PHP template file displays content based on requested URL, following predictable fallback pattern from specific to general templates. From single-post-slug.php specificity to index.php fallback, understanding template hierarchy enables precise control over content presentation across post types, taxonomies, and page templates. This comprehensive guide teaches hierarchy visualization, template selection logic, conditional tags, custom template creation, and debugging techniques identifying active templates.

How Template Hierarchy Works

Request Flow:

  1. User requests URL: example.com/category/news/
  2. WordPress identifies request type: Category archive
  3. WordPress searches for templates in order:
    • category-news.php (category slug)
    • category-5.php (category ID)
    • category.php (generic category)
    • archive.php (generic archive)
    • index.php (fallback)
  4. First matching template renders content

Fallback System:

WordPress searches from most specific to least specific until finding template file.

Example Hierarchy (single post):

single-{post-type}-{slug}.php
→ single-{post-type}.php
→ single.php
→ singular.php
→ index.php

Index.php – The Fallback

Ultimate Fallback:

index.php displays content when no specific template exists.

Required: Every theme must have index.php.

Example index.php:

<?php get_header(); ?>

<main id="main">
    <?php
    if (have_posts()) :
        while (have_posts()) :
            the_post();
            get_template_part('template-parts/content', get_post_type());
        endwhile;
    endif;
    ?>
</main>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Single Post Templates

Hierarchy:

single-{post-type}-{slug}.php
single-{post-type}.php
single.php
singular.php
index.php

Examples:

Post slug hello-world:

  • single-post-hello-world.php (most specific)
  • single-post.php
  • single.php
  • singular.php
  • index.php

Custom post type portfolio with slug web-design:

  • single-portfolio-web-design.php
  • single-portfolio.php
  • single.php
  • singular.php
  • index.php

single.php:

<?php get_header(); ?>

<main id="primary">
    <?php
    while (have_posts()) :
        the_post();
        ?>
        <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
            <header class="entry-header">
                <?php the_title('<h1>', '</h1>'); ?>
                <div class="entry-meta">
                    Posted on <?php echo get_the_date(); ?> by <?php the_author(); ?>
                </div>
            </header>

            <?php if (has_post_thumbnail()) : ?>
                <?php the_post_thumbnail('large'); ?>
            <?php endif; ?>

            <div class="entry-content">
                <?php the_content(); ?>
            </div>

            <footer class="entry-footer">
                <?php the_tags('<span class="tags">', ', ', '</span>'); ?>
            </footer>
        </article>

        <?php
        if (comments_open() || get_comments_number()) :
            comments_template();
        endif;
    endwhile;
    ?>
</main>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Page Templates

Hierarchy:

{custom-template}.php (selected via admin)
page-{slug}.php
page-{id}.php
page.php
singular.php
index.php

Examples:

Page slug about:

  • Custom template (if selected in admin)
  • page-about.php
  • page-42.php (if page ID is 42)
  • page.php
  • singular.php
  • index.php

page.php:

<?php get_header(); ?>

<main id="primary">
    <?php
    while (have_posts()) :
        the_post();
        ?>
        <article id="page-<?php the_ID(); ?>" <?php post_class(); ?>>
            <header class="entry-header">
                <?php the_title('<h1>', '</h1>'); ?>
            </header>

            <div class="entry-content">
                <?php the_content(); ?>
            </div>
        </article>
    <?php endwhile; ?>
</main>

<?php get_footer(); ?>

Custom Page Template:

template-fullwidth.php:

<?php
/**
 * Template Name: Full Width
 * Template Post Type: page, post
 */

get_header(); ?>

<main id="primary" class="full-width">
    <?php
    while (have_posts()) :
        the_post();
        the_content();
    endwhile;
    ?>
</main>

<?php get_footer(); ?>

Selectable via: Page edit screen → Page Attributes → Template

Category Archive Templates

Hierarchy:

category-{slug}.php
category-{id}.php
category.php
archive.php
index.php

Examples:

Category slug news (ID 5):

  • category-news.php
  • category-5.php
  • category.php
  • archive.php
  • index.php

category.php:

<?php get_header(); ?>

<main id="primary">
    <header class="page-header">
        <h1><?php single_cat_title(); ?></h1>
        <div class="category-description">
            <?php echo category_description(); ?>
        </div>
    </header>

    <?php if (have_posts()) : ?>
        <div class="posts-list">
            <?php
            while (have_posts()) :
                the_post();
                ?>
                <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                    <div class="entry-summary">
                        <?php the_excerpt(); ?>
                    </div>
                </article>
            <?php endwhile; ?>
        </div>

        <?php the_posts_pagination(); ?>
    <?php else : ?>
        <p>No posts found in this category.</p>
    <?php endif; ?>
</main>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Tag Archive Templates

Hierarchy:

tag-{slug}.php
tag-{id}.php
tag.php
archive.php
index.php

Examples:

Tag slug wordpress (ID 10):

  • tag-wordpress.php
  • tag-10.php
  • tag.php
  • archive.php
  • index.php

Custom Post Type Archives

Hierarchy:

archive-{post-type}.php
archive.php
index.php

Example:

Portfolio post type:

  • archive-portfolio.php
  • archive.php
  • index.php

archive-portfolio.php:

<?php get_header(); ?>

<main id="primary">
    <header class="page-header">
        <h1>Portfolio</h1>
    </header>

    <?php if (have_posts()) : ?>
        <div class="portfolio-grid">
            <?php
            while (have_posts()) :
                the_post();
                ?>
                <div class="portfolio-item">
                    <a href="<?php the_permalink(); ?>">
                        <?php the_post_thumbnail('medium'); ?>
                        <h3><?php the_title(); ?></h3>
                    </a>
                </div>
            <?php endwhile; ?>
        </div>

        <?php the_posts_pagination(); ?>
    <?php endif; ?>
</main>

<?php get_footer(); ?>

Custom Taxonomy Templates

Hierarchy:

taxonomy-{taxonomy}-{term}.php
taxonomy-{taxonomy}.php
taxonomy.php
archive.php
index.php

Example:

Taxonomy portfolio_category, term web-design:

  • taxonomy-portfolio_category-web-design.php
  • taxonomy-portfolio_category.php
  • taxonomy.php
  • archive.php
  • index.php

Author Archive Templates

Hierarchy:

author-{nicename}.php
author-{id}.php
author.php
archive.php
index.php

author.php:

<?php get_header(); ?>

<main id="primary">
    <header class="author-header">
        <div class="author-avatar">
            <?php echo get_avatar(get_the_author_meta('ID'), 150); ?>
        </div>
        <div class="author-info">
            <h1><?php echo get_the_author(); ?></h1>
            <p class="author-bio"><?php echo get_the_author_meta('description'); ?></p>
        </div>
    </header>

    <?php if (have_posts()) : ?>
        <div class="author-posts">
            <h2>Posts by <?php echo get_the_author(); ?></h2>
            <?php
            while (have_posts()) :
                the_post();
                get_template_part('template-parts/content', 'excerpt');
            endwhile;
            ?>
        </div>

        <?php the_posts_pagination(); ?>
    <?php endif; ?>
</main>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Date Archive Templates

Hierarchy:

date.php
archive.php
index.php

date.php:

<?php get_header(); ?>

<main id="primary">
    <header class="page-header">
        <h1>
            <?php
            if (is_day()) :
                printf('Archives: %s', get_the_date());
            elseif (is_month()) :
                printf('Archives: %s', get_the_date('F Y'));
            elseif (is_year()) :
                printf('Archives: %s', get_the_date('Y'));
            endif;
            ?>
        </h1>
    </header>

    <?php if (have_posts()) : ?>
        <?php
        while (have_posts()) :
            the_post();
            get_template_part('template-parts/content', 'archive');
        endwhile;
        ?>

        <?php the_posts_pagination(); ?>
    <?php endif; ?>
</main>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Search Results Template

Hierarchy:

search.php
index.php

search.php:

<?php get_header(); ?>

<main id="primary">
    <header class="page-header">
        <h1>
            <?php printf('Search Results for: %s', '<span>' . get_search_query() . '</span>'); ?>
        </h1>
    </header>

    <?php if (have_posts()) : ?>
        <?php
        while (have_posts()) :
            the_post();
            ?>
            <article>
                <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                <div class="entry-summary">
                    <?php the_excerpt(); ?>
                </div>
            </article>
        <?php endwhile; ?>

        <?php the_posts_pagination(); ?>
    <?php else : ?>
        <div class="no-results">
            <p>No results found. Please try different keywords.</p>
            <?php get_search_form(); ?>
        </div>
    <?php endif; ?>
</main>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

404 Error Template

Hierarchy:

404.php
index.php

404.php:

<?php get_header(); ?>

<main id="primary">
    <section class="error-404">
        <header class="page-header">
            <h1>404: Page Not Found</h1>
        </header>

        <div class="page-content">
            <p>The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.</p>

            <h2>Try searching:</h2>
            <?php get_search_form(); ?>

            <h2>Popular Posts:</h2>
            <?php
            $popular = new WP_Query(array(
                'posts_per_page' => 5,
                'orderby' => 'comment_count'
            ));

            if ($popular->have_posts()) :
                echo '<ul>';
                while ($popular->have_posts()) :
                    $popular->the_post();
                    echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
                endwhile;
                echo '</ul>';
                wp_reset_postdata();
            endif;
            ?>
        </div>
    </section>
</main>

<?php get_footer(); ?>

Attachment Template

Hierarchy:

{MIME_type}.php (image.php, video.php, application.php)
attachment.php
single-attachment-{slug}.php
single-attachment.php
single.php
singular.php
index.php

Front Page Template

Hierarchy:

front-page.php
home.php (if front page displays posts)
page.php (if static front page set)
index.php

front-page.php:

<?php get_header(); ?>

<main id="primary" class="front-page">
    <section class="hero">
        <h1>Welcome to Our Website</h1>
        <p>Featured content here</p>
    </section>

    <section class="recent-posts">
        <h2>Latest Posts</h2>
        <?php
        $recent_posts = new WP_Query(array(
            'posts_per_page' => 3,
        ));

        if ($recent_posts->have_posts()) :
            while ($recent_posts->have_posts()) :
                $recent_posts->the_post();
                get_template_part('template-parts/content', 'excerpt');
            endwhile;
            wp_reset_postdata();
        endif;
        ?>
    </section>
</main>

<?php get_footer(); ?>

Debugging Template Hierarchy

Show Active Template:

// Add to functions.php
add_filter('template_include', function($template) {
    if (current_user_can('manage_options')) {
        echo '<!-- Template: ' . basename($template) . ' -->';
    }
    return $template;
});

Query Monitor Plugin:

Install Query Monitor plugin to see:

  • Active template file
  • Template hierarchy checked
  • Conditional tags active

Conditional Tags:

Determine current page type:

is_home()           // Blog posts index
is_front_page()     // Front page (static or posts)
is_single()         // Single post
is_page()           // Single page
is_category()       // Category archive
is_tag()            // Tag archive
is_tax()            // Custom taxonomy archive
is_author()         // Author archive
is_date()           // Date archive
is_search()         // Search results
is_404()            // 404 error
is_archive()        // Any archive
is_singular()       // Single post or page

Conclusion

WordPress template hierarchy determines content display through systematic fallback from specific to general template files. Master single post hierarchy flowing from post-slug specificity to index.php fallback, understand archive template selection for categories, tags, and custom taxonomies, create custom page templates with Template Name headers, and utilize conditional tags identifying page types. Template hierarchy provides predictable template selection enabling precise control over WordPress content presentation across all post types and request types.

  1. Template Hierarchy Documentation
  2. Conditional Tags Reference
  3. Template Files List
  4. Query Monitor Plugin
  5. Interactive Template Hierarchy

Call to Action

Theme customizations need reliable backups. Backup Copilot Pro protects your WordPress theme files automatically. Safeguard your template modifications—start your free 30-day trial today!