函数文档

get_template_hierarchy()

💡 云策文档标注

概述

get_template_hierarchy() 函数用于根据给定的模板 slug 生成模板层级结构,返回一个字符串数组。该函数处理自定义模板、特定模板类型(如 front-page)以及通过正则匹配和条件逻辑构建层级,并始终将 'index' 作为后备模板。

关键要点

  • 函数接受三个参数:$slug(必需,模板 slug)、$is_custom(可选,指示是否为自定义模板,默认 false)、$template_prefix(可选,模板前缀,默认空字符串)。
  • 返回值为字符串数组,表示模板层级,顺序从最具体到最通用,最后总是包含 'index'。
  • 函数内部通过条件分支处理特殊情况:如 $slug 为 'index' 时直接返回,$is_custom 为 true 时返回特定层级,以及针对 'front-page' 等 slug 的特定处理。
  • 使用正则表达式和字符串匹配来解析 slug,添加相关模板类型(如 'archive'、'single'、'singular')到层级中。
  • 应用过滤器(如 {$template_type}_template_hierarchy)允许开发者修改返回的层级数组。

代码示例

function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = '' ) {
    if ( 'index' === $slug ) {
        return apply_filters( 'index_template_hierarchy', array( 'index' ) );
    }
    if ( $is_custom ) {
        return apply_filters( 'page_template_hierarchy', array( 'page', 'singular', 'index' ) );
    }
    if ( 'front-page' === $slug ) {
        return apply_filters( 'frontpage_template_hierarchy', array( 'front-page', 'home', 'index' ) );
    }
    // 更多处理逻辑...
}

注意事项

  • 始终将 'index' 作为最后一个后备模板添加到层级中,这是函数的核心设计原则。
  • 参数 $template_prefix 用于提取主模板类型(例如,从 'taxonomy-books' 中提取 'taxonomy'),影响层级构建。
  • 函数依赖于 WordPress 核心函数如 get_post_types() 和 get_taxonomies() 来获取注册的帖子类型和分类法。
  • 在 WordPress 6.1.0 版本中引入,使用时需确保环境兼容性。

📄 原文内容

Gets the template hierarchy for the given template slug to be created.

Description

Note: Always add index as the last fallback template.

Parameters

$slugstringrequired
The template slug to be created.
$is_custombooloptional
Indicates if a template is custom or part of the template hierarchy.

Default:false

$template_prefixstringoptional
The template prefix for the created template.
Used to extract the main template type, e.g.
in taxonomy-books the taxonomy is extracted.
Default empty string.

Return

string[] The template hierarchy.

Source

function get_template_hierarchy( $slug, $is_custom = false, $template_prefix = '' ) {
	if ( 'index' === $slug ) {
		/** This filter is documented in wp-includes/template.php */
		return apply_filters( 'index_template_hierarchy', array( 'index' ) );
	}
	if ( $is_custom ) {
		/** This filter is documented in wp-includes/template.php */
		return apply_filters( 'page_template_hierarchy', array( 'page', 'singular', 'index' ) );
	}
	if ( 'front-page' === $slug ) {
		/** This filter is documented in wp-includes/template.php */
		return apply_filters( 'frontpage_template_hierarchy', array( 'front-page', 'home', 'index' ) );
	}

	$matches = array();

	$template_hierarchy = array( $slug );
	// Most default templates don't have `$template_prefix` assigned.
	if ( ! empty( $template_prefix ) ) {
		list( $type ) = explode( '-', $template_prefix );
		// We need these checks because we always add the `$slug` above.
		if ( ! in_array( $template_prefix, array( $slug, $type ), true ) ) {
			$template_hierarchy[] = $template_prefix;
		}
		if ( $slug !== $type ) {
			$template_hierarchy[] = $type;
		}
	} elseif ( preg_match( '/^(author|category|archive|tag|page)-.+$/', $slug, $matches ) ) {
		$template_hierarchy[] = $matches[1];
	} elseif ( preg_match( '/^(taxonomy|single)-(.+)$/', $slug, $matches ) ) {
		$type           = $matches[1];
		$slug_remaining = $matches[2];

		$items = 'single' === $type ? get_post_types() : get_taxonomies();
		foreach ( $items as $item ) {
			if ( ! str_starts_with( $slug_remaining, $item ) ) {
					continue;
			}

			// If $slug_remaining is equal to $post_type or $taxonomy we have
			// the single-$post_type template or the taxonomy-$taxonomy template.
			if ( $slug_remaining === $item ) {
				$template_hierarchy[] = $type;
				break;
			}

			// If $slug_remaining is single-$post_type-$slug template.
			if ( strlen( $slug_remaining ) > strlen( $item ) + 1 ) {
				$template_hierarchy[] = "$type-$item";
				$template_hierarchy[] = $type;
				break;
			}
		}
	}
	// Handle `archive` template.
	if (
		str_starts_with( $slug, 'author' ) ||
		str_starts_with( $slug, 'taxonomy' ) ||
		str_starts_with( $slug, 'category' ) ||
		str_starts_with( $slug, 'tag' ) ||
		'date' === $slug
	) {
		$template_hierarchy[] = 'archive';
	}
	// Handle `single` template.
	if ( 'attachment' === $slug ) {
		$template_hierarchy[] = 'single';
	}
	// Handle `singular` template.
	if (
		str_starts_with( $slug, 'single' ) ||
		str_starts_with( $slug, 'page' ) ||
		'attachment' === $slug
	) {
		$template_hierarchy[] = 'singular';
	}
	$template_hierarchy[] = 'index';

	$template_type = '';
	if ( ! empty( $template_prefix ) ) {
		list( $template_type ) = explode( '-', $template_prefix );
	} else {
		list( $template_type ) = explode( '-', $slug );
	}
	$valid_template_types = array( '404', 'archive', 'attachment', 'author', 'category', 'date', 'embed', 'frontpage', 'home', 'index', 'page', 'paged', 'privacypolicy', 'search', 'single', 'singular', 'tag', 'taxonomy' );
	if ( in_array( $template_type, $valid_template_types, true ) ) {
		/** This filter is documented in wp-includes/template.php */
		return apply_filters( "{$template_type}_template_hierarchy", $template_hierarchy );
	}
	return $template_hierarchy;
}

Changelog

Version Description
6.1.0 Introduced.