28 KiB
前端资源加载优化
自 WordPress 5.8 版本起,开发者可配置仅在前端渲染时加载指定区块类型的脚本与样式。此功能适用于 block.json 文件中的以下资源字段:
scriptviewScriptstyleviewStyle(WordPress 6.5.0 版本新增)
国际化支持
WordPress 字符串发现系统可自动翻译本文档中标记为可翻译的字段。首先需在提供区块元数据的 block.json 文件中设置 textdomain 属性。
示例:
{
"title": "我的区块",
"description": "我的区块非常出色",
"keywords": [ "出色" ],
"textdomain": "我的插件"
}
PHP 实现
在 PHP 中,当执行 register_block_type 时,本地化属性将在 WordPress 后端自动包裹在 _x 函数调用中。这些翻译会以内联脚本形式添加到插件的脚本句柄或 WordPress 核心的 wp-block-library 脚本句柄。
register_block_type 处理可翻译值的方式大致等效于以下代码段:
<?php
$metadata = array(
'title' => _x( '我的区块', '区块标题', '我的插件' ),
'description' => _x( '我的区块非常出色!', '区块描述', '我的插件' ),
'keywords' => array( _x( '出色', '区块关键词', '我的插件' ) ),
);
该实现遵循现有的 get_plugin_data 函数逻辑,通过解析插件内容获取元数据,并动态应用翻译。
JavaScript 实现
在 JavaScript 中,可通过 @wordpress/blocks 包的 registerBlockType 方法,传入从 block.json 加载的元数据对象作为首参数。所有本地化属性会自动包裹在 _x(来自 @wordpress/i18n 包)函数调用中,其运作机制与 PHP 端类似。
示例:
import { registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import metadata from './block.json';
registerBlockType( metadata, {
edit: Edit,
// ...其他客户端设置
} );
向后兼容性
现有注册机制(服务端与前端)将继续生效,它将作为基于 block.json 注册方式的底层实现细节。
待所有细节完善后,核心区块将进行迭代迁移,第三方区块将在控制台中收到警告提示,建议重构现有区块注册 API。
以下属性将继续在客户端保持向后兼容,部分属性未来可能被替代 API 取代:
edit- 详见编辑与保存文档save- 详见编辑与保存文档transforms- 详见转换器文档deprecated- 详见废弃区块文档merge- 当前未收录文档,用于处理多区块合并功能getEditWrapperProps- 同样未收录文档,用于向区块编辑组件包装器注入额外属性
示例:
import { registerBlockType } from '@wordpress/blocks';
registerBlockType( '我的插件/区块名称', {
edit: function () {
// 编辑定义
},
save: function () {
// 保存定义
},
getEditWrapperProps: function () {
// 实现逻辑
},
} );
对于 WordPress 支持的动态区块,仍可通过服务端的 register_block_type 函数注册 render_callback 属性。
在 block.json 中定义元数据
自 WordPress 5.8 版本起,我们建议使用 block.json 元数据文件作为通过 PHP(服务端)和 JavaScript(客户端)注册区块类型的标准方式。以下是一个示例 block.json 文件,用于为插件创建通知区块定义元数据。
示例:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "my-plugin/notice",
"title": "通知",
"category": "text",
"parent": [ "core/group" ],
"icon": "star",
"description": "显示警告、错误或成功通知...",
"keywords": [ "警示", "消息" ],
"version": "1.0.3",
"textdomain": "my-plugin",
"attributes": {
"message": {
"type": "string",
"source": "html",
"selector": ".message"
}
},
"providesContext": {
"my-plugin/message": "message"
},
"usesContext": [ "groupId" ],
"selectors": {
"root": ".wp-block-my-plugin-notice"
},
"supports": {
"align": true
},
"styles": [
{ "name": "default", "label": "默认", "isDefault": true },
{ "name": "other", "label": "其他" }
],
"example": {
"attributes": {
"message": "这是一个通知!"
}
},
"variations": [
{
"name": "example",
"title": "示例",
"attributes": {
"message": "这是一个示例!"
}
}
],
"editorScript": "file:./index.js",
"script": "file:./script.js",
"viewScript": [ "file:./view.js", "example-shared-view-script" ],
"editorStyle": "file:./index.css",
"style": [ "file:./style.css", "example-shared-style" ],
"viewStyle": [ "file:./view.css", "example-view-style" ],
"render": "file:./render.php"
}
使用元数据文件的优势
通过 JSON 格式存储区块类型时,区块定义支持在 JavaScript、PHP 和其他语言之间共享代码。而使用 block.json 元数据文件注册区块还能带来额外优势。
从性能角度来看,当主题支持资源懒加载时,通过 block.json 注册的区块将自动实现资源队列优化。在 style 或 script 属性中列出的前端 CSS 和 JavaScript 资源仅当区块出现在页面上时才会加入队列,从而减小页面体积。
此外,由于区块类型 REST API 接口仅能列出在服务端注册的区块,因此建议在服务端注册区块;使用 block.json 文件可简化此注册过程。
WordPress 插件目录能够检测 block.json 文件,高亮显示插件中包含的区块,并提取其元数据。若希望将区块提交至区块目录,则插件中包含的所有区块都必须具备 block.json 文件,以便区块目录识别它们。
通过使用预定义的架构描述文件可改善开发体验。支持的编辑器能够提供工具提示、自动补全和架构验证等辅助功能。要使用此架构,请在 block.json 文件顶部添加以下内容:
"$schema": "https://schemas.wp.org/trunk/block.json"
区块 API
本节描述所有可添加到 block.json 文件中用于定义区块类型行为和元数据的属性。
API 版本
- 类型:
number - 可选性:可选
- 本地化:不支持
- 属性:
apiVersion - 默认值:
1
{ "apiVersion": 3 }
区块所使用的 Block API 版本。最新版本为 3,随 WordPress 6.3 引入。
详见 API 版本文档 获取更多详细信息。
编辑器脚本
- 类型:
WPDefinedAsset|WPDefinedAsset[](了解更多) - 可选
- 是否本地化:否
- 属性:
editorScript
{ "editorScript": "file:./index.js" }
区块类型的编辑器脚本定义。这些脚本仅会在编辑器环境中加入队列。
可以传递使用 wp_register_script 函数注册的脚本句柄、相对于 block.json 文件的 JavaScript 文件路径,或包含两者混合的列表(了解更多)。
注意:从 WordPress 6.1.0 版本开始,支持传递编辑器脚本数组。
脚本
- 类型:
WPDefinedAsset|WPDefinedAsset[](了解更多) - 可选
- 是否本地化:否
- 属性:
script
{ "script": "file:./script.js" }
区块类型的前端和编辑器脚本定义。这些脚本会在编辑器环境和网站前端查看内容时同时加入队列。
可以传递使用 wp_register_script 函数注册的脚本句柄、相对于 block.json 文件的 JavaScript 文件路径,或包含两者混合的列表(了解更多)。
注意:从 WordPress 6.1.0 版本开始,支持传递脚本数组。
视图脚本
- 类型:
WPDefinedAsset|WPDefinedAsset[](了解更多) - 可选
- 是否本地化:否
- 属性:
viewScript - 自:
WordPress 5.9.0
{ "viewScript": [ "file:./view.js", "example-shared-view-script" ] }
区块类型的前端脚本定义。这些脚本仅会在网站前端查看内容时加入队列。
可以传递使用 wp_register_script 函数注册的脚本句柄、相对于 block.json 文件的 JavaScript 文件路径,或包含两者混合的列表(了解更多)。
注意:从 WordPress 6.1.0 版本开始,支持传递视图脚本数组。
视图脚本模块
- 类型:
WPDefinedAsset|WPDefinedAsset[](了解更多) - 可选
- 是否本地化:否
- 属性:
viewScriptModule - 自:
WordPress 6.5.0
{ "viewScriptModule": [ "file:./view.js", "example-shared-script-module-id" ] }
区块类型的前端脚本模块定义。这些模块仅会在网站前端查看内容时加入队列。
可以传递使用 wp_register_script_module 函数注册的脚本模块 ID、相对于 block.json 文件的 JavaScript 模块路径,或包含两者混合的列表(了解更多)。
目前 WordPress 脚本与 WordPress 脚本模块不兼容。如果前端视图资源依赖于 WordPress 脚本,应使用 viewScript;如果依赖于 WordPress 脚本模块(当前为交互性 API),则应使用 viewScriptModule。脚本模块的更多功能将逐步开放。
注意:此功能自 WordPress 6.5.0 版本起可用。
编辑器样式
- 类型:
WPDefinedAsset|WPDefinedAsset[](了解更多) - 可选
- 是否本地化:否
- 属性:
editorStyle
{ "editorStyle": "file:./index.css" }
区块类型的编辑器样式定义。这些样式仅会在编辑器环境中加入队列。
可以传递使用 wp_register_style 函数注册的样式句柄、相对于 block.json 文件的 CSS 文件路径,或包含两者混合的列表(了解更多)。
注意:从 WordPress 5.9.0 版本开始,支持传递编辑器样式数组。
名称
- 类型:
字符串 - 必需
- 是否本地化:否
- 属性:
name
{ "name": "core/heading" }
区块名称是用于标识区块的唯一字符串。名称必须遵循 命名空间/区块名称 的结构,其中命名空间是插件或主题的名称。
注意: 区块名称只能包含小写字母数字字符、连字符,且最多只能包含一个正斜杠用于表示插件唯一的命名空间前缀。名称必须以字母开头。
注意: 此名称在注释分隔符中使用,格式为 <!-- wp:my-plugin/book -->。属于 core 命名空间的区块类型在序列化时不包含命名空间。
标题
- 类型:
字符串 - 必需
- 是否本地化:是
- 属性:
title
{ "title": "标题" }
这是区块的显示标题,可以通过翻译函数进行翻译。标题将显示在插入器及编辑器的其他区域中。
注意: 为了确保区块标题在用户界面中易于阅读和访问,请尽量避免使用过长的标题。
分类
- 类型:
字符串 - 可选
- 是否本地化:否
- 属性:
category
{ "category": "文本" }
区块按分类进行分组,以帮助用户浏览和发现它们。
核心提供的分类包括:
- 文本
- 媒体
- 设计
- 小工具
- 主题
- 嵌入
插件和主题还可以注册自定义区块分类。
实现应预期并容忍未知分类,并提供合理的回退行为(例如使用“文本”分类)。
父级
- 类型:
字符串数组 - 可选
- 是否本地化:否
- 属性:
parent
{ "parent": [ "my-block/product" ] }
设置 parent 可以让一个区块仅在嵌套于指定区块内时才可用。例如,可以允许“加入购物车”区块仅在“产品”区块内可用。
祖先
- 类型:
字符串数组 - 可选
- 是否本地化:否
- 属性:
ancestor - 自:
WordPress 6.0.0
{ "ancestor": [ "my-block/product" ] }
ancestor 属性使区块可以在指定区块类型的子树中的任何位置使用。例如,可以在“列”区块中放置“评论内容”区块,只要“列”区块位于“评论模板”区块的子树中。与 parent 属性相比,指定了 ancestor 的区块可以放置在子树的任何位置,而指定了 parent 的区块必须是直接子级。
允许的区块
- 类型:
字符串数组 - 可选
- 是否本地化:否
- 属性:
allowedBlocks - 自:
WordPress 6.5.0
{ "allowedBlocks": [ "my-block/product" ] }
allowedBlocks 指定哪些区块类型可以作为该区块的直接子级。例如,“列表”区块可以仅允许“列表项”区块作为子级。
图标
- 类型:
字符串 - 可选
- 是否本地化:否
- 属性:
icon
{ "icon": "smile" }
应指定图标属性以便更容易识别区块。图标可以是 WordPress 的 Dashicons 中的任意图标(在非 JavaScript 环境中,图标别名也可作为回退)。
注意: 也可以通过客户端使用 SVG 元素的源来覆盖此属性。此外,此属性可以通过 JavaScript 定义为包含背景色和前景色的对象。这些颜色将在适用时与图标一起显示,例如在插入器中。自定义 SVG 图标会自动包装在 wp.primitives.SVG 组件中,以添加可访问性属性(aria-hidden、role 和 focusable)。
描述
- 类型:
字符串 - 可选
- 是否本地化:是
- 属性:
description
{
"description": "引入新板块并组织内容,以帮助访客更好地浏览"
}
这是区块的简短描述,可以通过翻译函数进行翻译。此描述将显示在区块检查器中。
关键词
- 类型:
string[] - 可选
- 支持本地化:是
- 属性:
keywords - 默认值:
[]
{ "keywords": [ "keyword1", "keyword2" ] }
有时,一个区块可以设置别名,帮助用户在搜索时发现它。例如,图片区块可能还希望通过“照片”一词被搜索到。您可以通过提供不限数量的术语数组(这些术语会被翻译)来实现此功能。
版本
- 类型:
string - 可选
- 支持本地化:否
- 属性:
version - 自:
WordPress 5.8.0
{ "version": "1.0.3" }
区块的当前版本号,例如 1.0 或 1.0.3。这与插件版本管理类似。此字段可能与区块资源一起用于控制缓存失效,如果区块作者未提供此字段,则使用已安装的 WordPress 版本号代替。
文本域
- 类型:
string - 可选
- 支持本地化:否
- 属性:
textdomain - 自:
WordPress 5.7.0
{ "textdomain": "my-plugin" }
插件/区块的 gettext 文本域。更多信息请参见如何国际化您的插件页面中的文本域部分。
属性
- 类型:
object - 可选
- 支持本地化:否
- 属性:
attributes - 默认值:
{}
{
"attributes": {
"cover": {
"type": "string",
"source": "attribute",
"selector": "img",
"attribute": "src"
},
"author": {
"type": "string",
"source": "html",
"selector": ".book-author"
}
}
}
属性提供了区块的结构化数据需求。它们在序列化时可以以不同形式存在,但在通用接口下统一声明。
更多详情请参阅属性文档。
提供上下文
- 类型:
object - 可选
- 支持本地化:否
- 属性:
providesContext - 默认值:
{}
以对象形式提供上下文,将上下文名称映射到区块自身的某个属性,供该类型区块的子级访问。
更多详情请参阅区块上下文文档。
{
"providesContext": {
"my-plugin/recordId": "recordId"
}
}
上下文
- 类型:
string[] - 可选
- 支持本地化:否
- 属性:
usesContext - 默认值:
[]
要从祖先提供者继承的上下文值名称数组。
更多详情请参阅区块上下文文档。
{
"usesContext": [ "message" ]
}
选择器
- 类型:
object - 可选
- 支持本地化:否
- 属性:
selectors - 默认值:
{} - 自:
WordPress 6.3.0
在生成 theme.json(全局样式)样式表的区块样式时使用的任何自定义 CSS 选择器,按 root、功能或子功能作为键。提供自定义选择器可以更精细地控制样式应用于哪些区块元素,例如,仅将排版样式应用于内部标题,而颜色样式仍应用于外部区块包装器等。
更多详情请参阅选择器文档。
{
"selectors": {
"root": ".my-custom-block-selector",
"color": {
"text": ".my-custom-block-selector p"
},
"typography": {
"root": ".my-custom-block-selector > h2",
"text-decoration": ".my-custom-block-selector > h2 span"
}
}
}
支持功能
- 类型:
object - 可选
- 支持本地化:否
- 属性:
supports - 默认值:
{}
包含一组用于控制编辑器中使用的功能的选项。更多详情请参阅支持功能文档。
区块样式
- 类型:
数组 - 可选
- 支持本地化:是(仅限
label字段) - 属性:
styles - 默认值:
[]
{
"styles": [
{ "name": "default", "label": "默认", "isDefault": true },
{ "name": "other", "label": "其他" }
]
}
区块样式可用于为区块提供替代样式,其实现原理是通过在区块包装器上添加类名。主题开发者可以利用 CSS 针对已选定的区块样式类名进行样式定制。
插件和主题还可以为现有区块注册自定义区块样式。
示例配置
- 类型:
对象 - 可选
- 支持本地化:否
- 属性:
example
{
"example": {
"attributes": {
"message": "这是一个通知!"
}
}
}
该配置用于为区块提供结构化的示例数据。当用户将鼠标悬停在区块上时,这些数据将用于在检查器帮助面板中构建区块预览效果。
更多详细信息请参阅示例配置文档。
区块变体
- 类型:
对象数组|WP预定义路径(了解更多) - 可选
- 支持本地化:是(仅限各变体的
title、description和keywords字段) - 属性:
variations - 版本要求:
WordPress 5.9.0及以上
{
"variations": [
{
"name": "example",
"title": "示例",
"attributes": {
"level": 2,
"message": "这是一个示例!"
},
"scope": [ "block" ],
"isActive": [ "level" ]
}
]
}
区块变体 API 允许一个区块拥有多个相似版本,这些版本共享某些通用功能。每个区块变体通过设置不同的初始属性或内部区块来相互区分。当插入区块时,这些属性和/或内部区块会被自动应用。
注意:在 JavaScript 中可为 isActive 属性提供函数,为 icon 属性提供 React 元素。而在 block.json 文件中,这两个属性仅支持字符串类型
从 6.7 版本开始,可以在 block.json 中指定一个 PHP 文件来在服务端生成区块变体列表:
{ "variations": "file:./variations.php" }
该 PHP 文件需要返回包含区块变体的数组。从 PHP 文件返回的变体中的字符串不会自动本地化,需照常使用 __() 函数进行处理。
例如:
<?php
// 为社交图标类区块生成变体
return array(
array(
'isDefault' => true,
'name' => 'wordpress',
'title' => 'WordPress',
'icon' => 'wordpress',
'attributes' => array(
'service' => 'wordpress',
),
'isActive' => array( 'service' )
),
array(
'name' => 'mail',
'title' => __( '邮件' ),
'keywords' => array(
__( '邮箱' ),
__( '电子邮件' )
),
'icon' => 'mail',
'attributes' => array(
'service' => 'mail',
),
'isActive' => array( 'mail' )
),
);
更多详细信息请参阅变体文档。
区块钩子
- 类型:
对象 - 可选
- 属性:
blockHooks - 版本要求:
WordPress 6.4.0及以上
{
"blockHooks": {
"my-plugin/banner": "after"
}
}
区块钩子 API 允许区块自动插入到指定区块类型的所有实例旁,其相对位置也由被"挂钩"的区块指定。即区块可以选择插入到指定区块类型的前后,或作为其首个子区块/最后一个子区块(即分别在其子区块列表的开头或末尾添加)。被挂钩的区块将同时在前端和编辑器中显示(以便用户进行自定义)。
配置中的键是要挂钩的区块名称(字符串),值是要挂钩的位置(字符串)。请参阅区块钩子文档了解更多可用配置信息。
样式
- 类型:
WPDefinedAsset|WPDefinedAsset[](了解更多) - 可选
- 是否本地化:否
- 属性:
style
{ "style": [ "file:./style.css", "example-shared-style" ] }
区块类型的前端和编辑器样式定义。这些样式将在编辑器和前端查看内容时同时加载。
可以传递通过 wp_register_style 函数注册的样式句柄、相对于 block.json 文件的 CSS 文件路径,或包含两者的混合列表(了解更多)。
注意:从 WordPress 5.9.0 版本开始,支持传递样式数组。
查看样式
- 类型:
WPDefinedAsset|WPDefinedAsset[](了解更多) - 可选
- 是否本地化:否
- 属性:
viewStyle - 自版本:
WordPress 6.5.0
{ "viewStyle": [ "file:./view.css", "example-view-style" ] }
区块类型的前端样式定义。这些样式仅在前端查看内容时加载。
可以传递通过 wp_register_style 函数注册的样式句柄、相对于 block.json 文件的 CSS 文件路径,或包含两者的混合列表(了解更多)。
仅前端样式特别适用于交互式区块,用于样式化仅在用户执行某些操作后可见的部分,且这些样式在编辑器中永远不需要。你可以先使用 style 属性将所有通用样式放在一个样式表中。仅当需要特定于编辑器的样式或特定于前端的样式时,可以扩展使用 editorStyle 和 viewStyle,但仍将样式的主要通用部分保留在主样式表中。
渲染
- 类型:
WPDefinedPath(了解更多) - 可选
- 是否本地化:否
- 属性:
render - 自版本:
WordPress 6.1.0
{ "render": "file:./render.php" }
在服务器上渲染区块类型以在前端显示时使用的 PHP 文件。该文件暴露以下变量:
$attributes(array):区块属性。$content(string):区块默认内容。$block(WP_Block):区块实例。
使用 render 定义的 render.php 文件的示例实现可能如下:
<div <?php echo get_block_wrapper_attributes(); ?>>
<?php echo esc_html( $attributes['label'] ); ?>
</div>
注意:在服务器上渲染页面 HTML 时,此文件会为每个区块类型的实例加载。在文件中声明函数或类时,必须考虑到这一点。避免错误风险的最简单方法是从另一个文件调用共享逻辑。
资源
WPDefinedPath
WPDefinedPath 类型是字符串的子类型,其值表示相对于 block.json 文件位置的 JavaScript、CSS 或 PHP 文件路径。提供的路径必须以 file: 为前缀。此方法基于 npm 处理包的本地路径的方式。
示例:
在 block.json 中:
{
"render": "file:./render.php"
}
WPDefinedAsset
它扩展了 WPDefinedPath,适用于 JavaScript 和 CSS 文件。文件路径的替代方案可以是脚本句柄、脚本模块 ID 或样式句柄,引用使用 WordPress 辅助函数已注册的资源。
示例:
在 block.json 中:
{
"editorScript": "file:./index.js",
"script": "file:./script.js",
"viewScriptModule": [
"file:./view.js",
"example-registered-script-module-id"
],
"editorStyle": "file:./index.css",
"style": [ "file:./style.css", "example-shared-style" ],
"viewStyle": [ "file:./view.css", "example-view-style" ]
}
在 WordPress 环境中,当使用 PHP 注册区块时,它将自动注册在 block.json 文件中找到的所有脚本、脚本模块和样式,并使用文件路径而非资源句柄。
这就是为什么 WPDefinedAsset 类型必须提供一种方式来镜像使用 wp_register_script、wp_register_script_module 和 wp_register_style 注册脚本、脚本模块和样式所需的参数,然后将这些参数作为与区块关联的句柄或脚本模块 ID。
可以提供具有以下结构的对象:
handle(string)- 脚本的名称。如果省略,将自动生成。dependencies(string[]|{ id: string, import?: 'dynamic'|'static' }[])- 此脚本依赖的已注册脚本句柄数组。脚本模块可以使用简单字符串表示静态依赖项,或使用对象形式表示动态依赖项。动态依赖项是可能在运行时使用或不使用的依赖项,通常与动态import('module-id')语法一起使用。默认值:[]。version(string|false|null)- 指定脚本版本号的字符串(如果有),将作为查询字符串添加到 URL 中以实现缓存清除。如果版本设置为false,则自动添加等于当前安装的 WordPress 版本的版本号。如果设置为null,则不添加版本。默认值:false。
该定义存储在一个单独的 PHP 文件中,该文件以 .asset.php 结尾,并位于 block.json 中列出的 JS/CSS 文件旁边。WordPress 将通过模式匹配自动检测此文件。此选项是首选,因为预计它将与 @wordpress/scripts 包一起自动生成这些资源文件。
示例:
build/
├─ block.json
├─ index.js
└─ index.asset.php
在 block.json 中:
{ "editorScript": "file:./index.js" }
在 build/index.asset.php 中:
<?php
return array(
'dependencies' => array(
'react',
'wp-blocks',
'wp-i18n',
),
'version' => '3be55b05081a63d8f9d0ecb466c42cfd',
);