各位观众老爷,晚上好! 欢迎来到今晚的 "WordPress源码八卦夜",我是今晚的主讲人,江湖人称“代码界的包打听”。 今天咱们要聊聊WordPress Block Editor(也就是古腾堡编辑器)里的两个关键角色:save
和 edit
方法。 别看它们名字简单,背后可是连接 React 组件、HTML 和 PHP 的秘密通道,堪称“前端撩后端”的经典案例。 准备好了吗? 咱们这就开始揭秘!
第一幕:edit
方法——前端小鲜肉的初次登场
首先,我们得搞清楚 edit
方法是干嘛的。 简单来说,edit
方法就是负责在 WordPress 后台 Block Editor 里渲染区块编辑界面的。 它是一个 React 组件,定义了用户如何与区块交互,比如输入文字、选择颜色、上传图片等等。
// 示例:一个简单的文本区块的 edit 方法
const Edit = (props) => {
const { attributes, setAttributes } = props;
const { content } = attributes;
const onChangeContent = (newContent) => {
setAttributes({ content: newContent });
};
return (
<div className="my-custom-block">
<textarea
value={content}
onChange={(e) => onChangeContent(e.target.value)}
placeholder="请输入内容..."
/>
</div>
);
};
export default Edit;
代码解释:
props
:这是 React 组件的标准参数,包含了区块的所有属性和方法。attributes
: 存储区块的数据,比如文本内容、颜色、大小等。setAttributes
: 更新attributes
的方法,一旦调用,就会触发区块的重新渲染,并通知 WordPress 保存数据。onChangeContent
:当用户在textarea
中输入内容时,这个函数会被调用,它会使用setAttributes
更新content
属性。
可以看到,edit
方法的核心就是:
- 展示界面:使用 React 组件渲染出用户可交互的界面。
- 收集数据:监听用户的操作,比如输入、点击、选择等。
- 更新属性:使用
setAttributes
将用户输入的数据保存到区块的attributes
中。
第二幕:save
方法——前端绅士的优雅转身
save
方法的任务是将 edit
方法中收集到的数据转换成 HTML 代码,最终存储到 WordPress 数据库中。 它也是一个 React 组件,但它的返回值是一个 HTML 元素(或者 null,如果不需要渲染任何内容)。
// 示例:对应上面文本区块的 save 方法
const Save = (props) => {
const { attributes } = props;
const { content } = attributes;
return (
<div className="my-custom-block">
<p>{content}</p>
</div>
);
};
export default Save;
代码解释:
attributes
:同样包含了区块的所有属性。- 返回值:是一个包含
content
属性的p
标签。
可以看到,save
方法的核心就是:
- 接收数据:从
attributes
中获取区块的数据。 - 生成 HTML:根据数据生成对应的 HTML 代码。
第三幕:attributes
——连接前端和后端的桥梁
attributes
在 edit
和 save
方法之间扮演着至关重要的角色。 它就像一个数据中转站,将前端收集到的数据传递给后端。
attributes
的定义是在区块的注册信息中进行的,它决定了区块有哪些属性,以及每个属性的类型、默认值等等。
// 示例:文本区块的 attributes 定义
registerBlockType('my-plugin/my-block', {
// ... 其他配置
attributes: {
content: {
type: 'string',
default: '',
},
},
edit: Edit,
save: Save,
});
代码解释:
type
:指定属性的类型,可以是string
、number
、boolean
、array
、object
等。default
:指定属性的默认值。
attributes
的作用:
- 数据校验:WordPress 会根据
attributes
的定义对数据进行校验,确保数据的类型和格式正确。 - 数据序列化:WordPress 会将
attributes
中的数据序列化成字符串,存储到数据库中。 - 数据反序列化:当区块被加载时,WordPress 会将数据库中的字符串反序列化成
attributes
对象,传递给edit
和save
方法。
第四幕:PHP 的登场——幕后英雄的默默付出
前面我们一直在说前端的事情,但 WordPress 毕竟是一个 PHP 程序,最终的数据还是要存储到 PHP 的数据库中。 那么,PHP 在这个过程中扮演着什么角色呢?
- 区块注册:虽然区块的
edit
和save
方法是用 JavaScript 编写的,但区块的注册信息(包括attributes
的定义)需要在 PHP 中进行。
// 示例:在 PHP 中注册区块
function my_plugin_register_block() {
register_block_type( 'my-plugin/my-block', array(
'attributes' => array(
'content' => array(
'type' => 'string',
'default' => '',
),
),
'render_callback' => 'my_plugin_render_block',
) );
}
add_action( 'init', 'my_plugin_register_block' );
代码解释:
register_block_type
:注册区块的函数。render_callback
:指定一个 PHP 函数,用于在前端渲染区块。
-
数据存储:当用户点击“发布”或“更新”按钮时,WordPress 会将所有区块的 HTML 代码保存到
wp_posts
表的post_content
字段中。 -
前端渲染:当用户访问页面时,WordPress 会从
post_content
字段中取出 HTML 代码,直接输出到页面上。 -
动态区块:除了将 HTML 代码直接存储到数据库中,WordPress 还支持动态区块。 动态区块是指在前端渲染时,会调用 PHP 函数生成 HTML 代码的区块。 动态区块的
save
方法返回null
,表示不需要保存任何 HTML 代码。
// 示例:动态区块的渲染函数
function my_plugin_render_block( $attributes ) {
$content = $attributes['content'];
$current_time = date( 'Y-m-d H:i:s' );
return '<div class="my-dynamic-block"><p>' . $content . ' - ' . $current_time . '</p></div>';
}
代码解释:
$attributes
:包含了区块的所有属性。- 返回值:是一个包含当前时间的 HTML 代码。
动态区块的优点是可以根据服务器端的数据动态生成 HTML 代码,比如显示当前时间、查询数据库等等。
第五幕:ServerSideRender
组件——懒人福音,后端渲染神器
如果你不想编写 save
方法,或者你的区块完全依赖于后端数据,那么可以使用 ServerSideRender
组件。 ServerSideRender
组件会自动将 attributes
发送到后端,由 PHP 函数生成 HTML 代码,然后将 HTML 代码渲染到前端。
// 示例:使用 ServerSideRender 组件
import ServerSideRender from '@wordpress/server-side-render';
const Edit = (props) => {
const { attributes } = props;
return (
<div className="my-custom-block">
<ServerSideRender
block="my-plugin/my-block"
attributes={attributes}
/>
</div>
);
};
export default Edit;
代码解释:
block
:指定区块的名称。attributes
:将attributes
传递给后端。
使用 ServerSideRender
组件的优点是可以简化前端代码,将所有的渲染逻辑都放在后端处理。
第六幕:block.json
——区块的配置文件
从 WordPress 5.8 开始,推荐使用 block.json
文件来定义区块的元数据,包括 attributes
、edit
、save
等。 block.json
文件是一个 JSON 文件,位于区块的根目录下。
// 示例:block.json 文件
{
"name": "my-plugin/my-block",
"title": "My Custom Block",
"description": "A simple text block.",
"category": "common",
"icon": "text",
"supports": {
"html": false
},
"attributes": {
"content": {
"type": "string",
"default": ""
}
},
"textdomain": "my-plugin",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style.css"
}
代码解释:
name
:区块的名称。title
:区块的标题,显示在 Block Editor 中。description
:区块的描述。category
:区块的分类。icon
:区块的图标。supports
:区块支持的功能,比如 HTML 编辑。attributes
:区块的属性。textdomain
:区块的文本域,用于国际化。editorScript
:区块的编辑脚本。editorStyle
:区块的编辑样式。style
:区块的前端样式。
使用 block.json
文件可以更好地组织区块的代码,并提高代码的可读性和可维护性。
总结:前端后端的完美配合
让我们用一张表格来总结一下 edit
和 save
方法,以及它们与 PHP 之间的关系:
角色 | 功能 | 技术 | 数据来源 | 数据去向 |
---|---|---|---|---|
edit |
编辑界面 | React | 无 | attributes |
save |
生成 HTML | React | attributes |
数据库/前端 |
PHP | 区块注册/渲染 | PHP | attributes |
前端 |
总而言之,edit
和 save
方法是 WordPress Block Editor 中连接前端和后端的关键桥梁。 edit
方法负责在前端收集数据,save
方法负责将数据转换成 HTML 代码,PHP 负责注册区块、存储数据和渲染页面。 三者相互配合,共同完成了区块的创建、编辑和显示。
最后,给大家留个思考题:
如果我想创建一个可以从 WordPress 数据库中动态获取数据的区块,我应该如何使用 edit
、save
和 PHP 来实现呢? 欢迎大家在评论区留言,分享你的想法!
今天的“WordPress源码八卦夜”就到这里,感谢大家的收看! 我们下期再见!