WordPress Template Hierarchy

When someone opens a URL, WordPress must choose one template file from the theme. The rule it follows is the template hierarchy. It starts with the most specific file name and goes to the more general ones. At the end it always finds index.php.

The main order

Page typeFiles WordPress looks for, in order
Front pagefront-page.php, then home.php or page.php (depends on the setting), then index.php
Blog posts listhome.php, index.php
Single postsingle-{post-type}-{slug}.php, single-{post-type}.php, single.php, singular.php, index.php
Pagepage-{slug}.php, page-{id}.php, page.php, singular.php, index.php
Categorycategory-{slug}.php, category-{id}.php, category.php, archive.php, index.php
Tagtag-{slug}.php, tag.php, archive.php, index.php
Custom post type archivearchive-{post-type}.php, archive.php, index.php
Search resultssearch.php, index.php
404 error404.php, index.php

Test it for real

We create a theme where every template only prints its own file name, so we can see which one WordPress picks. First only index.php exists:

Terminal output

$ for u in / /hello-world/ /sample-page/ /category/uncategorized/ "/?s=hello" /no-such-page/; do echo "$u => $(curl -s http://example.com$u)"; done
/ => index.php
/hello-world/ => index.php
/sample-page/ => index.php
/category/uncategorized/ => index.php
/?s=hello => index.php
/no-such-page/ => index.php

Everything uses index.php. Now we add three more templates: single.php, page.php and archive.php.

Terminal output

$ echo "<?php echo 'single.php';" > wp-content/themes/tc-theme/single.php
$ echo "<?php echo 'page.php';" > wp-content/themes/tc-theme/page.php
$ echo "<?php echo 'archive.php';" > wp-content/themes/tc-theme/archive.php
$ for u in / /hello-world/ /sample-page/ /category/uncategorized/ "/?s=hello" /no-such-page/; do echo "$u => $(curl -s http://example.com$u)"; done
/ => index.php
/hello-world/ => single.php
/sample-page/ => page.php
/category/uncategorized/ => archive.php
/?s=hello => index.php
/no-such-page/ => index.php

Now each type has its own file. The search page and the 404 page still use index.php. Let us add a more specific file for one page and a front page:

Terminal output

$ echo "<?php echo 'page-sample-page.php';" > wp-content/themes/tc-theme/page-sample-page.php
$ echo "<?php echo 'category-uncategorized.php';" > wp-content/themes/tc-theme/category-uncategorized.php
$ echo "<?php echo 'search.php';" > wp-content/themes/tc-theme/search.php
$ echo "<?php echo '404.php';" > wp-content/themes/tc-theme/404.php
$ echo "<?php echo 'front-page.php';" > wp-content/themes/tc-theme/front-page.php
$ for u in / /hello-world/ /sample-page/ /category/uncategorized/ "/?s=hello" /no-such-page/; do echo "$u => $(curl -s http://example.com$u)"; done
/ => front-page.php
/hello-world/ => single.php
/sample-page/ => page-sample-page.php
/category/uncategorized/ => category-uncategorized.php
/?s=hello => search.php
/no-such-page/ => 404.php

The most specific file wins: page-sample-page.php beats page.php, and category-uncategorized.php beats archive.php.

Find out the current template

While you work, you can print the template of the current page from wp_footer, with the global variable $template:

add_action( 'wp_footer', function () {
	global $template;
	echo '<!-- Template: ' . basename( $template ) . ' -->';
} );

Custom page templates

You can also create a template which an editor chooses on a page. Add a comment at the top of the file, and it will show in the page settings:

<?php
/*
Template Name: Full Width Page
Template Post Type: page
*/
Note: Use the template hierarchy to keep the code clean: do not use big if conditions inside one file when a separate template file can do the job. Next: Enqueue Scripts and Styles.

Congratulations! Chapter Finished. Learn more about the similar topics:
Exercises & Assignments
No Content Found.
Interview Questions & Answers
No Content Found.