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 type | Files WordPress looks for, in order |
|---|---|
| Front page | front-page.php, then home.php or page.php (depends on the setting), then index.php |
| Blog posts list | home.php, index.php |
| Single post | single-{post-type}-{slug}.php, single-{post-type}.php, single.php, singular.php, index.php |
| Page | page-{slug}.php, page-{id}.php, page.php, singular.php, index.php |
| Category | category-{slug}.php, category-{id}.php, category.php, archive.php, index.php |
| Tag | tag-{slug}.php, tag.php, archive.php, index.php |
| Custom post type archive | archive-{post-type}.php, archive.php, index.php |
| Search results | search.php, index.php |
| 404 error | 404.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:
$ 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.
$ 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:
$ 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
*/
| Exercises & Assignments |
|---|
| No Content Found. |
| Interview Questions & Answers |
|---|
| No Content Found. |