WordPress源码深度解析之:`Block Editor`的`save`和`edit`方法:`React`组件如何与`HTML`和`PHP`交互。

各位观众老爷,晚上好! 欢迎来到今晚的 "WordPress源码八卦夜",我是今晚的主讲人,江湖人称“代码界的包打听”。 今天咱们要聊聊WordPress Block Editor(也就是古腾堡编辑器)里的两个关键角色:saveedit 方法。 别看它们名字简单,背后可是连接 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 方法的核心就是:

  1. 展示界面:使用 React 组件渲染出用户可交互的界面。
  2. 收集数据:监听用户的操作,比如输入、点击、选择等。
  3. 更新属性:使用 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 方法的核心就是:

  1. 接收数据:从 attributes 中获取区块的数据。
  2. 生成 HTML:根据数据生成对应的 HTML 代码。

第三幕:attributes——连接前端和后端的桥梁

attributeseditsave 方法之间扮演着至关重要的角色。 它就像一个数据中转站,将前端收集到的数据传递给后端。

attributes 的定义是在区块的注册信息中进行的,它决定了区块有哪些属性,以及每个属性的类型、默认值等等。

// 示例:文本区块的 attributes 定义
registerBlockType('my-plugin/my-block', {
  // ... 其他配置
  attributes: {
    content: {
      type: 'string',
      default: '',
    },
  },
  edit: Edit,
  save: Save,
});

代码解释:

  • type:指定属性的类型,可以是 stringnumberbooleanarrayobject 等。
  • default:指定属性的默认值。

attributes 的作用:

  • 数据校验:WordPress 会根据 attributes 的定义对数据进行校验,确保数据的类型和格式正确。
  • 数据序列化:WordPress 会将 attributes 中的数据序列化成字符串,存储到数据库中。
  • 数据反序列化:当区块被加载时,WordPress 会将数据库中的字符串反序列化成 attributes 对象,传递给 editsave 方法。

第四幕:PHP 的登场——幕后英雄的默默付出

前面我们一直在说前端的事情,但 WordPress 毕竟是一个 PHP 程序,最终的数据还是要存储到 PHP 的数据库中。 那么,PHP 在这个过程中扮演着什么角色呢?

  1. 区块注册:虽然区块的 editsave 方法是用 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 函数,用于在前端渲染区块。
  1. 数据存储:当用户点击“发布”或“更新”按钮时,WordPress 会将所有区块的 HTML 代码保存到 wp_posts 表的 post_content 字段中。

  2. 前端渲染:当用户访问页面时,WordPress 会从 post_content 字段中取出 HTML 代码,直接输出到页面上。

  3. 动态区块:除了将 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 文件来定义区块的元数据,包括 attributeseditsave 等。 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 文件可以更好地组织区块的代码,并提高代码的可读性和可维护性。

总结:前端后端的完美配合

让我们用一张表格来总结一下 editsave 方法,以及它们与 PHP 之间的关系:

角色 功能 技术 数据来源 数据去向
edit 编辑界面 React attributes
save 生成 HTML React attributes 数据库/前端
PHP 区块注册/渲染 PHP attributes 前端

总而言之,editsave 方法是 WordPress Block Editor 中连接前端和后端的关键桥梁。 edit 方法负责在前端收集数据,save 方法负责将数据转换成 HTML 代码,PHP 负责注册区块、存储数据和渲染页面。 三者相互配合,共同完成了区块的创建、编辑和显示。

最后,给大家留个思考题:

如果我想创建一个可以从 WordPress 数据库中动态获取数据的区块,我应该如何使用 editsave 和 PHP 来实现呢? 欢迎大家在评论区留言,分享你的想法!

今天的“WordPress源码八卦夜”就到这里,感谢大家的收看! 我们下期再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注