跳到正文
原文
Gutenberg Times(区块编辑器)· Ryan Welcher·· 2026-07-22编辑评分63

WordPress 如何判断主题是否为 block theme

How WordPress decides a theme is a “block theme”

编辑导读

WordPress 判断主题是否为 block theme,只检查 templates/index.html 或旧版 block-templates/index.html 是否存在且可读。

“区块主题”这个术语在 WordPress 中经常被使用,但就代码层面而言,它究竟意味着什么,一直没有真正弄清楚。

在研究《文章编辑器将全面采用 iframe:WordPress 7.1 之前区块开发者需要了解的事项》时,我了解到测试 WordPress 7.1 Beta 1 的结果可能会让该计划有所软化:核心团队或许不会强制所有人使用 iframe,而可能只对区块主题强制实施;使用 apiVersion 2 或更低版本区块的经典主题则继续保持当前 7.0 的行为。(链接文章详细介绍了 7.0 阶段的完整情况。)

如果确实按这种方式划分,那么“区块主题”的准确定义就 suddenly 变得非常重要。那么,核心代码究竟检查什么?

公开 API 是 wp_is_block_theme(),它只是向当前启用的主题询问:

PHP

// wp-includes/theme.php (guard clause trimmed)
function wp_is_block_theme() {
	return wp_get_theme()->is_block_theme();
}

而 WP_Theme::is_block_theme() 完整来看只是一项文件存在性检查:

PHP

// wp-includes/class-wp-theme.php (caching trimmed)
public function is_block_theme() {
	$paths_to_index_block_template = array(
		$this->get_file_path( '/templates/index.html' ),
		$this->get_file_path( '/block-templates/index.html' ),
	);

	foreach ( $paths_to_index_block_template as $path ) {
		if ( is_file( $path ) && is_readable( $path ) ) {
			return true;
		}
	}

	return false;
}

如果主题提供了 index.html 区块模板,它就是“区块主题”,无论该模板位于 templates/,还是位于 block-templates/(5.9 之前的旧位置)。除此之外不会检查任何其他内容。这会带来一些可能令人意外的结果:

theme.json 并不会让你成为区块主题。 图案、区块模板部分或 add_theme_support( 'block-templates' ) 也都不会。一个主题可以采用所有这些“混合式”功能,却仍然被归入这项检查的经典主题一侧,因为测试只会寻找顶层的 index.html 模板。

子主题会继承这一判定结果。 get_file_path() 会先在子主题中查找,找不到时再回退到父主题,因此区块主题的子主题也是区块主题,即使子主题本身没有提供任何模板。

这是一项文件系统检查,而不是声明。 style.css 中没有任何头部信息可让你选择加入或退出。只要把 templates/index.html 放入主题中,就 WordPress 而言,它就是区块主题。

区块主题与经典主题所需的最少文件

这就是一个最小可行的区块主题所需的全部内容——两个文件:

Markdown

my-block-theme/
├── style.css          ← standard theme header
└── templates/
    └── index.html     ← this file IS the decider

(如果主题包含 style.css,并且同时具备 index.php 或 templates/index.html 中的任意一个,WordPress 就会认为该主题有效;这意味着对于区块主题而言,index.php、functions.php,甚至 theme.json 都是可选的。)

而以下主题则保证保持为经典主题:

Markdown

my-classic-theme/
├── style.css
└── index.php          ← the classic fallback template

要在这项检查中保持经典主题一侧,需要满足两个条件:

  1. 没有 templates/index.html,也没有旧版 block-templates/index.html。 其他区块模板无关紧要:一个包含 `templates/single.html` 但没有 `templates/index.html` 的主题,测试结果仍为经典主题。(不过实际上,如果你要提供区块模板,就应同时提供 index 模板,有意识地成为区块主题。)
  2. 没有区块主题父主题。 这项检查会回退到父主题,因此 Twenty Twenty-Five 的子主题无论包含什么内容,都是区块主题。要成为经典主题,整条主题层级链都必须符合条件。

其他一切都不受限制。theme.json、图案、add_theme_support( 'block-template-parts' )` 由插件注册的自定义模板——都不会切换这一判定。图案、add_theme_support( 'block-template-parts' )、由插件注册的自定义模板:都不会切换这一判定。

实际主题的归类情况

对主题目录中当前发布的一些版本运行这项检查所得的结果

测试结果为经典主题测试结果为区块主题
Twenty Twenty-One 以及所有更早的默认主题Twenty Twenty-Two 以及所有更晚的默认主题
Astra、Kadence、Blocksy、Botiga、Sydney、Hello Elementor——全部都提供 theme.json
GeneratePress、Neve、OceanWP、Storefront

第一栏中的六个主题都提供 theme.json,也就是主打的“区块”功能,但仍然是经典主题,因为该检查从未查看 theme.json

Twenty Twenty 和 OceanWP 又是两个容易踩坑的例子:它们都提供 templates/ 目录,却仍然是经典主题,因为该目录中充满了 PHP 页面模板(template-cover.php、landing.php)。这项检查 specifically 要求的是 templates/index.html,所以“它是否有一个 templates 文件夹”并不是你可能以为的判断依据。

编辑器如何读取它

在 JavaScript 端,区块主题标志会在两个不同的地方出现;如果你准备深入查看源码,这一点值得了解。

作为编辑器设置:

PHP

// wp-includes/block-editor.php, get_block_editor_settings()
$editor_settings['__unstableIsBlockBasedTheme'] = wp_is_block_theme();

以及在 REST 主题端点上,@wordpress/core-data 正是在那里读取它:

PHP

// wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php
$data['is_block_theme'] = $theme->is_block_theme();

单文件开关


尽管“区块主题”这个术语听起来分量十足,但它归根结底取决于一个文件:templates/index.html 存在,或者不存在。不是 theme.json,不是 patterns,也不是任何程度的混合式采用。就是一个索引模板,并且会沿父主题链向上检查。

如果 7.1 最终确实把 iframe 的分界线划在 wp_is_block_theme() 上,这一点就值得记住。一个已经采用了所有内容、除了区块模板的混合式主题,仍会保留经典编辑器的行为;而仅仅添加一个 templates/index.html(哪怕是误加,甚至是在你无法控制的父主题中)就会让站点切换为强制使用 iframe。如果你的主题或用户的站点处于这条线附近,现在正是检查自己实际上站在哪一边的好时机:只需一次 is_file() 调用即可确认。

来源:Gutenberg Times(区块编辑器) · https://gutenbergtimes.com/how-wordpress-decides-a-theme-is-a-block-theme/

部分链接为推广/关联链接。