
在基于块编辑器的 FSE(Full Site Editing)主题(如 Twenty Twenty-Three)中,.html 模板文件默认不解析 PHP。直接改名 .php 无效,正确方式是通过自定义 PHP 模式(Pattern)或模板函数间接执行逻辑。
在基于块编辑器的 fse(full site editing)主题(如 twenty twenty-three)中,`.html` 模板文件默认不解析 php。直接改名 `.php` 无效,正确方式是通过自定义 php 模式(pattern)或模板函数间接执行逻辑。
WordPress 的全站点编辑(FSE)主题采用基于 HTML 的模板结构(如 single.html),其核心设计原则是声明式、无服务端逻辑——所有模板文件均以纯 HTML + 块注释(<!-- wp:xxx -->)形式存在,由 WordPress 在渲染时动态解析为 HTML,不经过 PHP 解析引擎。因此,即使将 single.html 重命名为 single.php,WordPress 的模板层级机制仍会跳过它(因 FSE 主题禁用传统 PHP 模板回退逻辑),转而使用 index.html 作为兜底,导致自定义失效。
✅ 正确实现方式:使用自定义 PHP 模式(PHP Pattern)
FSE 主题支持通过 wp-block-patterns 注册可复用的 PHP 渲染模式。这是官方推荐、安全且可维护的方案:
-
在子主题的 functions.php 中注册 PHP 模式:
// 子主题 functions.php function mytheme_register_php_pattern() { if (!function_exists('register_block_pattern')) { return; } // 定义一个带 PHP 执行能力的模式(注意:内容需经 esc_html() 等安全处理) $pattern_content = ' <!-- wp:group {"className":"my-php-output"} --> <div class="my-php-output"> <!-- wp:paragraph --> <p>' . esc_html(wp_get_current_user()->display_name ?? '访客') . '</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>当前时间:' . esc_html(date_i18n(get_option('date_format') . ' H:i')) . '</p> <!-- /wp:paragraph --> </div> <!-- /wp:group --> '; register_block_pattern( 'mytheme/single-page-php-output', array( 'title' => __('单页动态内容', 'mytheme'), 'description' => __('在 single.html 中嵌入用户信息与时间等动态 PHP 数据', 'mytheme'), 'content' => $pattern_content, 'categories' => array('text'), ) ); } add_action('init', 'mytheme_register_php_pattern'); -
在 single.html 中插入该模式(使用 wp:pattern 块):
立即学习“PHP免费学习笔记(深入)”;
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
<!-- wp:spacer {"height":32} /-->
<!-- wp:pattern {"slug":"mytheme/single-page-php-output"} /--> <!-- ✅ 关键:插入 PHP 模式 -->
<!-- wp:post-content {"layout":{"inherit":true}} /-->
<!-- wp:spacer {"height":32} /-->
<!-- wp:group {"layout":{"inherit":true}} -->
...
> ⚠️ 注意事项:
> - **禁止在 HTML 模板中直接写 `<?php ... ?>`**:FSE 主题完全忽略此类标签,存在安全风险且无法执行;
> - **始终对 PHP 输出做转义**:使用 `esc_html()`、`esc_url()` 等函数防止 XSS;
> - **优先使用 Block API 替代硬编码逻辑**:例如用 `wp:post-date`、`wp:post-author` 等原生块替代手动 PHP 时间/作者输出;
> - **必须使用子主题开发**:直接修改官方主题(如 Twenty Twenty-Three)会导致更新后丢失;
> - 若需复杂逻辑(如数据库查询、条件判断),应封装为自定义区块(Custom Block)或通过 `wp_add_inline_script()` 注入前端 JS + REST API 调用。
### ✅ 替代方案:使用 `get_template_part()`(仅限子主题内)
若必须在模板中调用 PHP 文件,可在子主题中创建 `template-parts/php-dynamic.php`,并在 `functions.php` 中扩展模板加载逻辑:
```php
// functions.php 中添加
function mytheme_load_php_part($slug) {
$file = get_stylesheet_directory() . "/template-parts/php-{$slug}.php";
if (file_exists($file)) {
include $file;
}
}然后在自定义 PHP 模式中调用:
$content = '<div class="dynamic-section">';
ob_start();
mytheme_load_php_part('single-header');
$content .= ob_get_clean();
$content .= '</div>';但此方式绕过块编辑器可视化体验,维护成本高,仅建议用于遗留逻辑迁移。
综上,在 FSE 主题中“插入 PHP”的本质,不是让 HTML 执行 PHP,而是将 PHP 逻辑封装为可注入的块内容单元。遵循这一范式,既能保障主题兼容性与安全性,又能满足动态内容需求。


















