title: "区块的静态或动态渲染" post_status: publish comment_status: open taxonomy: category: - gutenberg-docs post_tag: - Fundamentals - Getting Started - Repos
区块的静态或动态渲染
区块的前端标记可以在请求时由服务器端动态生成(动态区块),也可以在区块编辑器的保存过程中静态生成(静态区块)。本文将探讨这两种方法。
静态渲染
采用"静态渲染"的区块在保存时会生成固定的前端输出并存储在数据库中。这些区块完全依赖其 save 函数来定义其 HTML 标记,除非在区块编辑器中手动编辑,否则这些标记保持不变。
如果一个区块不使用动态渲染方法——即页面加载时不通过 PHP 实时生成内容——它就被视为"静态区块"。
下图展示了静态区块内容如何保存在数据库中,然后在前端检索并渲染为 HTML。

如何为区块定义静态渲染
在客户端注册区块时可以定义的 save 函数,用于指定在编辑器中保存区块时存入数据库的区块 HTML 结构。随后,保存的 HTML 将用于在前端显示该区块。
WordPress 中的区块被封装在特殊的注释标签内,这些标签作为唯一的区块分隔符。然而,只有静态区块 save 函数中定义的 HTML(不包括这些分隔符)会被渲染。
查看预格式化区块中的静态渲染示例
以下是预格式化核心区块的
save 函数:
import { RichText, useBlockProps } from '@wordpress/block-editor';
export default function save( { attributes } ) {
const { content } = attributes;
return (
<pre { ...useBlockProps.save() }>
<RichText.Content value={ content } />
</pre>
);
}
<!-- wp:preformatted -->
<pre class="wp-block-preformatted">这是一些预格式化文本</pre>
<!-- /wp:preformatted -->
<pre class="wp-block-preformatted">这是一些预格式化文本</pre>
动态区块(我们将在下一节探讨)可以通过 save 函数指定初始 HTML 结构,类似于静态区块。然而,动态区块主要依赖服务器端渲染来生成其内容。如果由于任何原因(例如区块插件被停用)导致动态渲染不可用,系统将回退到使用数据库中保存的 HTML 结构来在前端显示区块。
要了解其工作原理的实际演示,请参阅构建你的第一个区块教程。特别是添加静态渲染部分,它说明了区块如何同时具备保存的 HTML 结构和动态渲染能力。
render_block 和 render_callback 函数等机制,用于在区块保存的 HTML 显示在前端之前对其进行修改。这些工具使开发者能够动态定制区块输出,以满足复杂和交互式的用户体验需求。
其他使用静态渲染的 WordPress 区块示例(即其输出在保存时即已固定,不依赖于服务器端处理)包括:
动态渲染
具有"动态渲染"功能的区块旨在前端请求时实时生成其内容和结构。与静态区块(在数据库中保存固定 HTML 结构)不同,"动态区块"依赖服务器端处理来动态构建输出,使其具有高度灵活性,适合需要频繁更新或依赖外部数据的内容。
下图展示了动态区块的表示形式如何保存在数据库中,然后在前端检索并动态渲染为 HTML。

动态区块有一些常见的应用场景:
- 内容应变化而文章未更新的区块: 例如最新文章区块,每当有新文章发布时它会自动更新。
- 标记更新应立即在前端显示的区块: 如果您通过添加新类、添加 HTML 元素或以任何其他方式更改布局来更新区块结构,使用动态区块可确保这些更改立即应用于站点上该区块的所有实例。如果没有动态区块,类似的更新可能会在区块编辑器中触发验证错误。
如何为区块定义动态渲染
区块可以通过两种主要方式定义动态渲染:
- 使用可传递给
register_block_type()函数的render_callback参数。这对于纯 PHP 区块是必需的。 - 使用通常名为
render.php的独立 PHP 文件。该文件的路径应在block.json文件中使用render属性定义。
这两种方法都接收以下数据:
查看站点标题区块中的动态渲染示例
[站点标题](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/site-title) 区块使用以下 [`render_callback`](https://github.com/WordPress/gutenberg/blob/trunk/packages/block-library/src/site-title/index.php):
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,
// 如果是链接,则已预先转义。
$attributes['isLink'] ? $site_title : esc_html( $site_title )
);
}
<!-- wp:site-title /-->
<h1 class="wp-block-site-title"><a href="https://www.wp.org" target="_self" rel="home">我的 WordPress 网站</a></h1>
数据库中动态块的 HTML 表示(save)
对于动态块,save 回调函数可以只返回 null,这会告知编辑器仅将块分隔符注释(以及任何现有的块属性)保存到数据库。然后这些属性会被传递给服务器端渲染回调,由它决定如何在前端显示该块。
当 save 为 null 时,块编辑器将跳过块标记验证过程,避免因频繁变化的标记而产生问题。
具有动态渲染功能的块也可以保存块的 HTML 表示作为备份。如果你提供了服务器端渲染回调,数据库中代表该块的 HTML 将被回调的输出替换,但如果你的块被停用(注册该块的插件被卸载)或你的渲染回调被移除,则会渲染此 HTML。
在某些情况下,块会保存其 HTML 表示,并在满足某些条件时使用动态渲染来微调此标记。核心块中使用此方法的一些示例包括:
- 封面块在数据库中保存块的完整 HTML 表示。此标记通过
render_callback处理,如果启用了“使用特色图片”设置,它会动态注入特色图片。 - 图片块同样在数据库中保存其 HTML 表示。此标记通过
render_callback处理,如果满足特定条件,它会向标记添加额外属性。
如果你在动态块中使用 InnerBlocks,则需要在 save 回调函数中使用 <InnerBlocks.Content/> 来保存 InnerBlocks。
其他资源
- 静态与动态区块:有何区别? | 开发者博客
- 区块弃用教程 | 开发者博客