区块的前端标记可以动态生成(在请求时由服务器端动态生成)或在块编辑器保存过程中静态生成(静态块)。本文探讨每种方法。The post Static vs. dynamic blocks: What's the difference? 提供了该主题的绝佳介绍。
静态渲染
具有“静态渲染”的区块在保存时会产生固定并存储在数据库中的前端输出。这些区块仅依赖其 save 函数来定义其 HTML 标记,除非在块编辑器中手动编辑,否则保持不变。
如果区块不使用动态渲染方法——即它不会在页面加载时通过 PHP 即时生成内容——则被视为“静态块”。
下图说明了静态块内容如何保存在数据库中,然后检索并在前端作为 HTML 进行渲染。

如何为区块定义静态渲染
save 函数可以在 在客户端注册块时 定义,它指定每当您在编辑器中保存块时保存到数据库的块的 HTML 结构。然后使用此保存的 HTML 在前端显示块。
WordPress 中的区块封装在特殊的注释标签内,这些标签充当唯一的 块分隔符。但是,仅渲染静态块的 save 函数中定义的 HTML(不包括这些分隔符)。
import { RichText, useBlockProps } from '@wordpress/block-editor';
export default function save( { attributes } ) {
const { content } = attributes;
return (
<pre { ...useBlockProps.save() }>
<RichText.Content value={ content } />
</pre>
);
}
当 attributes.content 的值为 "This is some preformatted text" 时,该函数会生成块的以下标记表示:
<!-- wp:preformatted -->
<pre class="wp-block-preformatted">This is some preformatted text</pre>
<!-- /wp:preformatted -->
在前端,块将返回以下标记。请注意分隔符不再存在。
<pre class="wp-block-preformatted">This is some preformatted text</pre>
动态区块(我们将在下一节中探讨)可以通过 save 函数指定初始 HTML 结构,类似于静态块。但是,动态区块主要依赖服务器端渲染来生成其内容。如果出于任何原因不可用动态渲染——例如由于块的插件被停用——系统将回退到使用数据库中保存的 HTML 结构在前端显示块。
有关此工作原理的实际演示,请参阅 构建您的第一个区块 教程。特别是,添加静态渲染 部分说明了块如何同时具有保存的 HTML 结构和动态渲染功能。
WordPress 提供了诸如render_block 和 render_callback 函数之类的机制,以在块出现在前端之前更改块的保存 HTML。这些工具为开发人员提供了动态自定义块输出的能力,以满足复杂和交互式用户体验的需求。使用静态渲染的 WordPress 区块的其他示例(意味着其输出在保存时固定且不依赖服务器端处理)包括:
动态渲染
具有“动态渲染”的区块旨在在请求时实时生成其内容和结构。与具有保存在数据库中的固定 HTML 结构的静态块不同,“动态块”依赖服务器端处理来动态构建其输出,使其非常灵活,适合需要频繁更新或依赖于外部数据的内容。
下图说明了动态块的表示如何保存在数据库中,然后检索并在前端动态渲染为 HTML。

动态块有一些常见用例:
- 即使帖子未更新,内容也应发生变化的区块: 例如 最新文章 区块,每当发布新帖子时会自动更新。
- 对标记的更新应立即显示在前端的区块: 如果您通过添加新类、添加 HTML 元素或以其他方式更改布局来更新块的结构,使用动态块可确保这些更改立即应用于站点中该块的所有实例。没有动态块,类似的更新可能会在块编辑器中触发 验证错误。
如何为区块定义动态渲染
区块可以通过两种主要方式定义动态渲染:
- 使用可以传递给
register_block_type()函数的render_callback参数。这对于 仅 PHP 区块 是必需的。 - 使用通常名为
render.php的单独 PHP 文件。该文件的路径应使用block.json文件中的render属性定义。
这两种方法都接收以下数据:
在站点标题区块中查看动态渲染示例站点标题 块使用以下 render_callback:
function render_block_core_site_title( $attributes ) {
$site_title = get_bloginfo( 'name' );
if ( ! $site_title ) {
return;
}
$tag_name = 'h1';
$classes = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}";
if ( isset( $attributes['style']['elements']['link']['color']['text'] ) ) {
$classes .= ' has-link-color';
}
if ( isset( $attributes['level'] ) ) {
$tag_name = 0 === $attributes['level'] ? 'p' : 'h' . (int) $attributes['level'];
}
if ( $attributes['isLink'] ) {
$aria_current = is_home() || ( is_front_page() && 'page' === get_option( 'show_on_front' ) ) ? ' aria-current="page"' : '';
$link_target = ! empty( $attributes['linkTarget'] ) ? $attributes['linkTarget'] : '_self';
$site_title = sprintf(
'<a href="%1$s" target="%2$s" rel="home"%3$s>%4$s</a>',
esc_url( home_url() ),
esc_attr( $link_target ),
$aria_current,
esc_html( $site_title )
);
}
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => trim( $classes ) ) );
return sprintf(
'<%1$s %2$s>%3$s</%1$s>',
$tag_name,
$wrapper_attributes,
// already pre-escaped if it is a link.
$attributes['isLink'] ? $site_title : esc_html( $site_title )
);
}
然而,正如从其 index.js 文件中所见,该块没有定义 save 函数,这意味着数据库中该块的标记表示如下:
<!-- wp:site-title /-->
在前端,render_callback 用于根据服务器在请求块时的特定值动态渲染块的标记。这些值包括当前站点标题、URL、链接目标等。
<h1 class="wp-block-site-title"><a href="https://www.wp.org" target="_self" rel="home">My WordPress Website</a></h1>
数据库中动态块的 HTML 表示(保存)
对于动态块,save 回调函数可以仅返回 null,这指示编辑器仅将块分隔符注释(以及任何现有的 块属性)保存到数据库中。这些属性随后被传递给服务器端渲染回调,该回调将决定如何在站点的前端显示该块。
当 save 为 null 时,区块编辑器将跳过 块标记验证过程,从而避免因标记频繁变化而引发的问题。
具有动态渲染的块也可以保存块的 HTML 表示作为备份。如果您提供了服务器端渲染回调,数据库中代表块的 HTML 将被您的回调的输出替换,但如果您的块被停用(注册该块的插件被卸载),或者您的渲染回调被移除,则仍会进行渲染。
在某些情况下,块会保存块的 HTML 表示,并在满足某些条件时使用动态渲染来微调此标记。一些使用此方法的核心块的示例如下:
- 封面 块 保存 了数据库中块的完整 HTML 表示。此标记通过
render_callback进行处理,该回调 动态注入 特色图片,如果启用了“使用特色图片”设置。 - 图像 块也 保存 了其 HTML 表示到数据库中。此标记通过
render_callback进行处理,该回调 添加额外属性 到标记中,如果满足特定条件。
如果您在动态块中使用 InnerBlocks,则需要在 save 回调函数中保存 InnerBlocks,使用 <InnerBlocks.Content/>。
其他资源
- 静态块与动态块:有什么区别? | 开发者博客
- 块弃用 – 教程 | 开发者博客