各位朋友,大家好!我是老码农,今天咱们来聊聊WordPress古腾堡编辑器里一个挺有意思的小东西——block.json
,特别是里面的metadata
部分。别看它个头不大,作用可不小,搞清楚它,能让你在自定义区块的路上少踩不少坑。
咱们这次讲座的目标很简单:
- 理解
block.json
的地位和作用: 它是区块的“身份证”,没有它,区块就没法在古腾堡里混。 - 深入
metadata
: 搞清楚metadata
里各个字段的含义,以及它们是如何影响区块的行为的。 block.json
的底层解析: 看看WordPress是怎么读取和使用block.json
的。- 实战演练: 通过一些实际的例子,让你明白怎么用
metadata
来定制区块。
好了,废话不多说,咱们开始吧!
1. block.json
:区块的“身份证”
想象一下,你要在一个大型的社交场合(古腾堡编辑器)介绍自己(你的区块),你需要什么?当然是身份证啊!block.json
就是区块的身份证,它告诉WordPress:
- 我是谁(
name
) - 我长什么样(
attributes
定义了区块的数据结构) - 我有什么功能(
supports
定义了区块支持的功能) - 我在哪里(
file
指定了区块的脚本和样式文件)
一个最简单的block.json
可能长这样:
{
"name": "my-plugin/my-block",
"title": "My Block",
"category": "common",
"icon": "smiley",
"attributes": {
"content": {
"type": "string",
"default": "Hello, world!"
}
},
"supports": {
"align": true
},
"editorScript": "file:./index.js",
"style": "file:./style.css"
}
这个JSON文件告诉WordPress,我们有一个名为my-plugin/my-block
的区块,它显示一个笑脸图标,有一个可以编辑的文本内容,并且支持对齐。
2. metadata
:区块的“详细信息”
metadata
并不是block.json
里一个单独的字段。 实际上, block.json
就是 区块的元数据文件。 里面的每一个键值对,都描述了区块的不同方面的属性。它包含了区块的所有关键信息,包括但不限于:
apiVersion
: 指定区块API的版本。name
: 区块的唯一标识符,格式为plugin-slug/block-name
。title
: 区块在编辑器中显示的名字。description
: 区块的描述信息。category
: 区块所属的分类(common, formatting, layout, widgets, embed)。icon
: 区块的图标。可以是 Dashicons 的名称,也可以是 SVG 元素。keywords
: 关键词,方便用户搜索区块。attributes
: 定义区块的数据结构。每个属性都有一个type
(string, number, boolean, array, object)和一个default
值。supports
: 定义区块支持的功能,例如align
(对齐)、anchor
(锚点)、color
(颜色)、spacing
(间距)。providesContext
: 区块向子区块提供的上下文数据。usesContext
: 区块使用的上下文数据。example
: 区块的示例数据,用于在区块面板中预览。editorScript
: 编辑器中使用的 JavaScript 文件。editorStyle
: 编辑器中使用的 CSS 文件。style
: 前端使用的 CSS 文件。render
: PHP 回调函数,用于在前端渲染区块。textdomain
: 区块的文本域,用于国际化。parent
: 指定允许包含此区块的父区块。ancestor
: 指定允许此区块存在的祖先区块。variations
: 区块的变体。
这些字段就像是区块的“详细信息”,告诉WordPress这个区块是干什么的,怎么用。
3. block.json
的底层解析
WordPress在初始化古腾堡编辑器时,会扫描所有已注册的区块,并解析它们的block.json
文件。这个过程主要发生在WP_Block_Type_Registry
类中。
简单来说,WordPress会做以下几件事:
- 查找
block.json
: WordPress会根据区块的名称(例如my-plugin/my-block
)查找对应的block.json
文件。它会在插件目录、主题目录等地方查找。 - 读取和解析JSON: WordPress会读取
block.json
文件的内容,并将其解析成一个PHP数组。 - 创建
WP_Block_Type
对象: WordPress会根据解析后的数据,创建一个WP_Block_Type
对象。这个对象包含了区块的所有信息,例如名称、属性、支持的功能等。 - 注册区块类型: WordPress会将
WP_Block_Type
对象注册到WP_Block_Type_Registry
中。这样,古腾堡编辑器就能识别并使用这个区块了。
你可以通过以下代码来获取一个区块的WP_Block_Type
对象:
<?php
$block_type = WP_Block_Type_Registry::get_instance()->get( 'my-plugin/my-block' );
if ( $block_type ) {
// 现在你可以访问区块的各种属性了
echo '区块名称:' . $block_type->name . '<br>';
echo '区块标题:' . $block_type->title . '<br>';
// ...
} else {
echo '区块未找到!';
}
?>
这段代码演示了如何从WordPress的区块类型注册表中获取一个区块的信息。WP_Block_Type_Registry::get_instance()->get()
方法接收区块的名称作为参数,并返回一个 WP_Block_Type
对象,如果该区块存在的话。如果区块不存在,则返回 null
。通过这个对象,你可以访问区块的各种属性,比如名称、标题、属性等等。
4. 实战演练:用metadata
定制区块
光说不练假把式,咱们来通过几个例子,看看怎么用metadata
来定制区块。
例子1:自定义区块的对齐方式
假设你想让你的区块只支持居中对齐和靠右对齐,你可以这样修改block.json
:
{
"name": "my-plugin/my-block",
"title": "My Block",
"category": "common",
"icon": "smiley",
"attributes": {
"content": {
"type": "string",
"default": "Hello, world!"
}
},
"supports": {
"align": ["center", "right"]
},
"editorScript": "file:./index.js",
"style": "file:./style.css"
}
这样,在古腾堡编辑器中,你的区块就只会显示居中对齐和靠右对齐的选项了。
例子2:使用providesContext
和usesContext
传递数据
providesContext
允许一个区块向其子区块提供数据,而usesContext
允许一个区块使用其父区块提供的数据。
假设我们有一个父区块叫做my-plugin/parent-block
,它提供一个名为my-plugin/theme
的上下文,值为dark
或light
:
// block.json for my-plugin/parent-block
{
"name": "my-plugin/parent-block",
"title": "Parent Block",
"category": "common",
"icon": "smiley",
"attributes": {
"theme": {
"type": "string",
"default": "light"
}
},
"providesContext": {
"my-plugin/theme": "theme"
},
"editorScript": "file:./index.js",
"style": "file:./style.css"
}
然后在index.js
中,我们可以使用useBlockProps
和useSetting
来设置编辑器中的样式,并更新属性theme
:
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, SelectControl } from '@wordpress/components';
export default function Edit({ attributes, setAttributes }) {
const { theme } = attributes;
return (
<>
<InspectorControls>
<PanelBody title="Theme Settings">
<SelectControl
label="Theme"
value={theme}
options={[
{ label: 'Light', value: 'light' },
{ label: 'Dark', value: 'dark' },
]}
onChange={(newTheme) => setAttributes({ theme: newTheme })}
/>
</PanelBody>
</InspectorControls>
<div {...useBlockProps()}>
{/* Parent Block Content */}
<p>Parent Block - Theme: {theme}</p>
</div>
</>
);
}
现在,假设我们有一个子区块叫做my-plugin/child-block
,它想使用父区块提供的my-plugin/theme
上下文:
// block.json for my-plugin/child-block
{
"name": "my-plugin/child-block",
"title": "Child Block",
"category": "common",
"icon": "smiley",
"usesContext": ["my-plugin/theme"],
"editorScript": "file:./index.js",
"style": "file:./style.css"
}
然后在index.js
中,我们可以使用useContext
来获取父区块提供的theme
值:
import { useBlockProps, useContext } from '@wordpress/block-editor';
export default function Edit() {
const theme = useContext('my-plugin/theme');
return (
<div {...useBlockProps()}>
{/* Child Block Content */}
<p>Child Block - Theme: {theme || 'default'}</p>
</div>
);
}
这样,子区块就能根据父区块提供的theme
值来改变自己的样式或行为了。
例子3:使用variations
创建区块变体
区块变体允许你创建一个区块的多个版本,每个版本都有不同的属性和样式。
假设我们有一个名为my-plugin/button
的区块,它有两个变体:primary
和secondary
。
{
"name": "my-plugin/button",
"title": "Button",
"category": "common",
"icon": "button",
"attributes": {
"text": {
"type": "string",
"default": "Click me!"
},
"style": {
"type": "string",
"default": "primary"
}
},
"variations": [
{
"name": "primary",
"title": "Primary Button",
"description": "A primary button.",
"attributes": {
"style": "primary"
},
"icon": "button"
},
{
"name": "secondary",
"title": "Secondary Button",
"description": "A secondary button.",
"attributes": {
"style": "secondary"
},
"icon": "button"
}
],
"editorScript": "file:./index.js",
"style": "file:./style.css"
}
在index.js
中,我们可以根据style
属性来应用不同的样式:
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function Edit({ attributes, setAttributes }) {
const { text, style } = attributes;
let buttonClass = 'my-button';
if (style === 'primary') {
buttonClass += ' my-button-primary';
} else if (style === 'secondary') {
buttonClass += ' my-button-secondary';
}
return (
<button {...useBlockProps({ className: buttonClass })}>
<RichText
tagName="span"
value={text}
onChange={(newText) => setAttributes({ text: newText })}
/>
</button>
);
}
这样,用户就可以在古腾堡编辑器中选择创建primary
或secondary
按钮了。
5. 总结
block.json
是古腾堡区块的基石,而metadata
则是block.json
的核心。 掌握了metadata
的各个字段的含义,以及WordPress是如何解析和使用block.json
的,你就能更灵活地定制区块,创建出功能强大的自定义区块。
今天我们主要讲了:
block.json
是区块的“身份证”。metadata
包含了区块的所有关键信息。- WordPress会解析
block.json
,并将其转换为WP_Block_Type
对象。 - 可以通过
supports
、providesContext
、usesContext
和variations
等字段来定制区块。
希望这次讲座能让你对block.json
和metadata
有更深入的理解。 记住,实践是检验真理的唯一标准,多动手尝试,你才能真正掌握这些知识。
下次有机会,咱们再聊聊其他更有意思的WordPress开发话题! 谢谢大家!