函数文档

_get_block_templates_files()

💡 云策文档标注

概述

_get_block_templates_files() 函数用于从主题中检索模板文件,支持 'wp_template' 和 'wp_template_part' 两种类型。它接受模板类型和查询参数,返回符合条件的模板文件数组,若模板类型不匹配则返回 null。

关键要点

  • 函数参数:$template_type(必需,字符串,值为 'wp_template' 或 'wp_template_part')和 $query(可选,数组,用于过滤模板)。
  • 查询参数支持:slug__in(包含的 slug 列表)、slug__not_in(排除的 slug 列表)、area(仅用于 'wp_template_part' 的模板区域过滤)、post_type(针对 'wp_template' 的帖子类型过滤)。
  • 返回值为数组(成功时)或 null($template_type 不匹配时),数组包含模板的 slug、路径、主题和类型等信息。
  • 函数处理子主题和父主题的模板文件,优先使用子主题定义,并应用查询过滤逻辑。

代码示例

function _get_block_templates_files( $template_type, $query = array() ) {
    if ( 'wp_template' !== $template_type && 'wp_template_part' !== $template_type ) {
        return null;
    }

    $default_template_types = array();
    if ( 'wp_template' === $template_type ) {
        $default_template_types = get_default_block_template_types();
    }

    // Prepare metadata from $query.
    $slugs_to_include = isset( $query['slug__in'] ) ? $query['slug__in'] : array();
    $slugs_to_skip    = isset( $query['slug__not_in'] ) ? $query['slug__not_in'] : array();
    $area             = isset( $query['area'] ) ? $query['area'] : null;
    $post_type        = isset( $query['post_type'] ) ? $query['post_type'] : '';

    // ... 后续代码处理主题目录和模板文件过滤
}

注意事项

  • 函数内部依赖多个辅助函数,如 get_block_theme_folders() 和 _get_block_templates_paths(),需确保这些函数可用。
  • 在 WordPress 6.3.0 版本中增加了 $query 参数,增强了过滤能力。
  • 对于 'wp_template_part' 类型,使用 _add_block_template_part_area_info() 添加区域信息;对于 'wp_template' 类型,使用 _add_block_template_info() 添加模板信息。

📄 原文内容

Retrieves the template files from the theme.

Parameters

$template_typestringrequired
Template type. Either 'wp_template' or 'wp_template_part'.
$queryarrayoptional
Arguments to retrieve templates. Optional, empty by default.

  • slug__in string[]
    List of slugs to include.
  • slug__not_in string[]
    List of slugs to skip.
  • area string
    A 'wp_template_part_area' taxonomy value to filter by (for 'wp_template_part' template type only).
  • post_type string
    Post type to get the templates for.

Default:array()

Return

array|null Template files on success, null if $template_type is not matched.

Source

function _get_block_templates_files( $template_type, $query = array() ) {
	if ( 'wp_template' !== $template_type && 'wp_template_part' !== $template_type ) {
		return null;
	}

	$default_template_types = array();
	if ( 'wp_template' === $template_type ) {
		$default_template_types = get_default_block_template_types();
	}

	// Prepare metadata from $query.
	$slugs_to_include = isset( $query['slug__in'] ) ? $query['slug__in'] : array();
	$slugs_to_skip    = isset( $query['slug__not_in'] ) ? $query['slug__not_in'] : array();
	$area             = isset( $query['area'] ) ? $query['area'] : null;
	$post_type        = isset( $query['post_type'] ) ? $query['post_type'] : '';

	$stylesheet = get_stylesheet();
	$template   = get_template();
	$themes     = array(
		$stylesheet => get_stylesheet_directory(),
	);
	// Add the parent theme if it's not the same as the current theme.
	if ( $stylesheet !== $template ) {
		$themes[ $template ] = get_template_directory();
	}
	$template_files = array();
	foreach ( $themes as $theme_slug => $theme_dir ) {
		$template_base_paths  = get_block_theme_folders( $theme_slug );
		$theme_template_files = _get_block_templates_paths( $theme_dir . '/' . $template_base_paths[ $template_type ] );
		foreach ( $theme_template_files as $template_file ) {
			$template_base_path = $template_base_paths[ $template_type ];
			$template_slug      = substr(
				$template_file,
				// Starting position of slug.
				strpos( $template_file, $template_base_path . DIRECTORY_SEPARATOR ) + 1 + strlen( $template_base_path ),
				// Subtract ending '.html'.
				-5
			);

			// Skip this item if its slug doesn't match any of the slugs to include.
			if ( ! empty( $slugs_to_include ) && ! in_array( $template_slug, $slugs_to_include, true ) ) {
				continue;
			}

			// Skip this item if its slug matches any of the slugs to skip.
			if ( ! empty( $slugs_to_skip ) && in_array( $template_slug, $slugs_to_skip, true ) ) {
				continue;
			}

			/*
			 * The child theme items (stylesheet) are processed before the parent theme's (template).
			 * If a child theme defines a template, prevent the parent template from being added to the list as well.
			 */
			if ( isset( $template_files[ $template_slug ] ) ) {
				continue;
			}

			$new_template_item = array(
				'slug'  => $template_slug,
				'path'  => $template_file,
				'theme' => $theme_slug,
				'type'  => $template_type,
			);

			if ( 'wp_template_part' === $template_type ) {
				$candidate = _add_block_template_part_area_info( $new_template_item );
				if ( ! isset( $area ) || $area === $candidate['area'] ) {
					$template_files[ $template_slug ] = $candidate;
				}
			}

			if ( 'wp_template' === $template_type ) {
				$candidate = _add_block_template_info( $new_template_item );
				$is_custom = ! isset( $default_template_types[ $candidate['slug'] ] );

				if (
					! $post_type ||
					( $post_type && isset( $candidate['postTypes'] ) && in_array( $post_type, $candidate['postTypes'], true ) )
				) {
					$template_files[ $template_slug ] = $candidate;
				}

				// The custom templates with no associated post types are available for all post types.
				if ( $post_type && ! isset( $candidate['postTypes'] ) && $is_custom ) {
					$template_files[ $template_slug ] = $candidate;
				}
			}
		}
	}

	return array_values( $template_files );
}

Changelog

Version Description
6.3.0 Added the $query parameter.
5.9.0 Introduced.