Template Hierarchy – WordPress 模板层级

本文详细解释了 WordPress 如何决定调用哪个模板文件来显示具体页面。如果你想修改一个 WordPress 主题,本文的知识将帮助你决定具体修改哪个文件。

模板文件的层级

总览

WordPress 使用查询字符串决定使用哪个模板文件来显示页面,查询字符串是包含在链接地址中,位于问号之后,可能由”&”连接的一系列参数。

简单的说,WordPress 会搜索整个模板文件层级,直到找到一个匹配的模板文件。为了决定使用哪个文件,WordPress:

  1. 匹配所有查询字符串以决定请求的是哪个页面(比如,搜索页面,分类页面等)
  2. 按照模板层级指定的顺序搜索
  3. 在当前主题文件夹下寻找第一个匹配到的模板文件

如果 WordPress 找不到匹配的名字,它将跳至层级中的下一个文件。如果 WordPress 找不到任何匹配的文件,将使用主题的 index.php 文件。

例子

如果你的博客地址是 http://example.com/blog/,一位访客点击了你博客分类页面的一个链接 http://example.com/blog/category/your-cat/,那么 WordPress 将根据该分类的 ID 在当前主题的文件夹中寻找相符的模板文件,以生成正确页面。更具体的说,WordPress 遵循如下程序:

  1. 在当前主题文件夹下寻找匹配分类别名的模板文件。如果分类别名是"unicorns",WordPress 将寻找名为 category-unicorns.php 的模板文件。
  2. 如果 category-unicorns.php 没有找到,且该分类的 ID 为4的话,WordPress 将寻找名为 category-4.php 的模板文件。
  3. 如果 category-4.php 没有找到, WordPress 将寻找通用模板文件, category.php
  4. 如果 category.php 不存在, WordPress 将寻找通用存档文件, archive.php
  5. 如果 archive.php 仍然没有找到, WordPress 将退回至主模板文件, index.php

可视化总览

下面的图片根据 WordPress 的模板层级,展示了模板文件的调用顺序。

template-hierarchy

模板层级细说

尽管上面的图片更容易理解,本文接下来的部分还是用文字详细描述了不同类型页面的模板文件调用顺序。

首页(Home Page)

By default, WordPress sets your site’s home page to display your latest blog posts. This page is called the blog posts index. You can also set your blog posts to display on a separate static page. The template file home.php is used to render the blog posts index, whether it is being used as the front page or on separate static page. If home.php does not exist, WordPress will use index.php.

  1. home.php
  2. index.php

If front-page.php exists, it will override the home.php template.

首页(Front Page)

The front-page.php template file is used to render your site’s front page, whether the front page displays the blog posts index (mentioned above) or a static page. The front page template takes precedence over the blog posts index (home.php) template. If the front-page.php file does not exist, WordPress will either use the home.php orpage.php files depending on the setup in Settings → Reading. If neither of those files exist, it will use the index.php file.

  1. front-page.php – Used for both “your latest posts” or “a static page” as set in the front page displays section of Settings → Reading.
  2. home.php – If WordPress cannot find front-page.php and “your latest posts” is set in the front page displays section, it will look for home.php. Additionally, WordPress will look for this file when the posts page is set in the front page displays section.
  3. page.php – When “front page” is set in the front page displays section.
  4. index.php – When “your latest posts” is set in the front page displays section but home.php does not exist or when front page is set but page.php does not exist.

As you can see, there are a lot of rules to what path WordPress takes. Using the chart above is the best way to determine what WordPress will display.

Single Post

The single post template file is used to render a single post. WordPress uses the following path:

  1. single-{post-type}-{slug}.php – (Since 4.4) First, WordPress looks for a template for the specific post. For example, if post type is product and the post slug isdmc-12, WordPress would look for single-product-dmc-12.php.
  2. single-{post-type}.php – If the post type is product, WordPress would look for single-product.php.
  3. single.php – WordPress then falls back to single.php.
  4. singular.php – Then it falls back to singular.php.
  5. index.php – Finally, as mentioned above, WordPress ultimately falls back to index.php.

Single Page

The template file used to render a static page (page post-type). Note that unlike other post-types, page is special to WordPress and uses the following patch:

  1. custom template file – The page template assigned to the page. See get_page_templates().
  2. page-{slug}.php – If the page slug is recent-news, WordPress will look to use page-recent-news.php.
  3. page-{id}.php – If the page ID is 6, WordPress will look to use page-6.php.
  4. page.php
  5. singular.php
  6. index.php

Category

Rendering category archive index pages uses the following path in WordPress:

  1. category-{slug}.php – If the category’s slug is news, WordPress will look for category-news.php.
  2. category-{id}.php – If the category’s ID is 6, WordPress will look for category-6.php.
  3. category.php
  4. archive.php
  5. index.php

Tag

To display a tag archive index page, WordPress uses the following path:

  1. tag-{slug}.php – If the tag’s slug is sometag, WordPress will look for tag-sometag.php.
  2. tag-{id}.php – If the tag’s ID is 6, WordPress will look for tag-6.php.
  3. tag.php
  4. archive.php
  5. index.php

Custom Taxonomies

Custom taxonomies use a slightly different template file path:

  1. taxonomy-{taxonomy}-{term}.php – If the taxonomy is sometax, and taxonomy’s term is someterm, WordPress will look for taxonomy-sometax-someterm.php. In the case of post formats, the taxonomy is ‘post_format’ and the terms are ‘post-format-{format}. i.e. taxonomy-post_format-post-format-link.php for the link post format.
  2. taxonomy-{taxonomy}.php – If the taxonomy were sometax, WordPress would look for taxonomy-sometax.php.
  3. taxonomy.php
  4. archive.php
  5. index.php

Custom Post Types

Custom Post Types use the following path to render the appropriate archive index page.

  1. archive-{post_type}.php – If the post type is product, WordPress will look for archive-product.php.
  2. archive.php
  3. index.php

(For rendering a single post type template, refer to the single post display section above.)

Author display

Based on the above examples, rendering author archive index pages is fairly explanatory:

  1. author-{nicename}.php – If the author’s nice name is matt, WordPress will look for author-matt.php.
  2. author-{id}.php – If the author’s ID were 6, WordPress will look for author-6.php.
  3. author.php
  4. archive.php
  5. index.php

Date

Date-based archive index pages are rendered as you would expect:

  1. date.php
  2. archive.php
  3. index.php

Search Result

Search results follow the same pattern as other template types:

  1. search.php
  2. index.php

404 (Not Found)

Likewise, 404 template files are called in this order:

  1. 404.php
  2. index.php

Attachment

Rendering an attachment page (attachment post-type) requires following the follow path:

  1. MIME_type.php – it can be any MIME type (For example: image.php, video.php, application.php). For text/plain, the following path is used (in order):
    1. text.php
    2. plain.php
    3. text_plain.php
  2. attachment.php
  3. single-attachment.php
  4. single.php
  5. index.php

Filter Hierarchy

The WordPress template system lets you filter the hierarchy. This means that you can insert and change things at specific points of the hierarchy. The filter (located in theget_query_template() function) uses this filter name: "{$type}_template" where $type is a file name in the hierarchy without the .php extension.

Here is a complete list of all template types in the filter hierarchy:

  • index_template
  • 404_template
  • archive_template
  • author_template
  • category_template
  • tag_template
  • taxonomy_template
  • date_template
  • home_template
  • front_page_template
  • page_template
  • paged_template
  • search_template
  • single_template
  • text_template, plain_template, text_plain_template (all mime types)
  • attachment_template
  • comments_popup

Example

For example, let’s take the default author hierarchy:

  • author-{nicename}.php
  • author-{id}.php
  • author.php

To add author-{role}.php before author.php, we can manipulate the actual hierarchy using the ‘author_template’ template type. This allows a request for /author/username where username has the role of editor to display using author-editor.php if present in the current themes directory.

  1. function author_role_template( $templates = '' ) {
  2.     $author = get_queried_object();
  3.     $role = $author->roles[0];
  4.     if ( ! is_array( $templates ) && ! empty( $templates ) ) {
  5.         $templates = locate_template( array( "author-$role.php", $templates ), false );
  6.     } elseif ( empty( $templates ) ) {
  7.         $templates = locate_template( "author-$role.php", false );
  8.     } else {
  9.         $new_template = locate_template( array( "author-$role.php" ) );
  10.         if ( ! empty( $new_template ) ) {
  11.             array_unshift( $templates, $new_template );
  12.         }
  13.     }
  14.     return $templates;
  15. }
  16. add_filter( 'author_template', 'author_role_template' );

Template Hierarchy