WP DEVELOP

EP135. “第一个自定义 Block 类型:registerBlockType 基础”

首页 WordPress 开发课程 插件开发 CH2:插件里的 JS · EP135
约 12 分钟· #EP135#插件开发 CH2:插件里的 JS
🔒 登录后可标记已读

插件开发第二章开篇:用 JavaScript 注册一个全新的 Gutenberg Block 类型。先用 PHP 新建插件骨架,把一个测试用的 JS 文件挂到「Block 编辑器」专属的资源加载钩子上(不是普通的前台/后台通用钩子);再用 WordPress 提供的全局对象 wp.blocks.registerBlockType() 注册一个最简单的 Block,分别用 edit(编辑器里长什么样)和 save(保存进数据库、前台显示的是什么)两个函数描述它。这一讲刻意先用 WordPress 原生的 wp.element.createElement() 手写 HTML 结构,为下一讲引入更好用的 JSX 语法做对比铺垫。


涉及文件

  • wp-content/plugins/are-you-paying-attention/index.php (新建)
  • wp-content/plugins/are-you-paying-attention/test.js (新建)

代码实现

index.php(完整文件)

<?php

/*
  Plugin Name: Are You Paying Attention Quiz
  Description: Give your readers a multiple choice question.
  Version: 1.0
  Author: Brad
  Author URI: https://www.udemy.com/user/bradschiff/
*/

if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

class AreYouPayingAttention {
  function __construct() {
    add_action('enqueue_block_editor_assets', array($this, 'adminAssets'));
  }

  function adminAssets() {
    wp_enqueue_script('ournewblocktype', plugin_dir_url(__FILE__) . 'test.js', array('wp-blocks', 'wp-element'));
  }
}

$areYouPayingAttention = new AreYouPayingAttention();

test.js(完整文件)

wp.blocks.registerBlockType("ourplugin/are-you-paying-attention", {
  title: "Are You Paying Attention?",
  icon: "smiley",
  category: "common",
  edit: function () {
    return wp.element.createElement("h3", null, "Hello, this is from the admin editor screen.")
  },
  save: function () {
    return wp.element.createElement("h1", null, "This is the frontend.")
  }
})

关键改动点:

  • enqueue_block_editor_assets 是专属于 Block 编辑器页面的资源加载钩子,跟之前给普通后台页面加载资源用的 admin_enqueue_scripts 是不同的钩子——只在打开文章/页面编辑器时才会触发,不会影响其他后台页面
  • wp_enqueue_script($handle, $src, $deps) 的第三个参数(依赖数组)里写了 wp-blockswp-element——这两个是 WordPress 核心自带的 JS 包,分别提供 wp.blocks(注册/管理 Block 类型的工具)和 wp.element(WordPress 自己包装的一层类 React 元素创建工具)。声明依赖能确保浏览器先加载好这两个包,我们自己的脚本才能安全地使用 wp.blocks/wp.element 这些全局对象,不会出现「用到时还没加载好」的问题
  • wp.blocks.registerBlockType(name, config):第一个参数是 Block 的唯一标识符,格式固定是 命名空间/短名(这里是 ourplugin/are-you-paying-attention),命名空间通常用插件自己的名字,避免跟别的插件的 Block 撞名
  • 配置对象里的 title(用户在插入 Block 菜单里看到的名字)、icon(这里先用内建的 dashicon 短名 smiley)、category(决定这个 Block 出现在插入菜单的哪个分类下,common 是内建的通用分类)都是 WordPress 固定认的属性名,不能随便改
  • editsave 两个函数是一个 Block 类型的核心:edit 控制的是编辑器里这个 Block 长什么样(作者可以互动编辑的界面);save 控制的是最终存进数据库、前台访问者看到的内容——两者可以完全不同(这一讲故意让两者输出不同的标题级别和文字,来清楚区分这两个函数各自的职责)
  • wp.element.createElement(tag, props, children) 是 WordPress 提供的、不需要额外配置就能直接用的「创建 HTML 元素」的原生方式:第一个参数是标签名(字符串),第二个参数是属性对象(没有属性传 null),第三个参数是子内容(文字或更多嵌套元素)——这个函数本质上就是 React 的 createElement只是套了 WordPress 自己的命名空间

📌 前台渲染的本质save 函数返回的内容只是在你点击「更新/发布」的那一刻,被 WordPress 转换成一段静态 HTML 字符串(作为一个带特殊注释标记的 Block 序列化文本)存进数据库,前台访问者看到的页面完全不涉及 JavaScript 执行——数据库 post_content 字段里能直接看到类似 <!-- wp:ourplugin/are-you-paying-attention --> 这样的注释标记包裹着最终的 HTML。真正需要在前台跑 JavaScript(比如做互动问答的判分逻辑)要用课程后面才会讲到的另一种技巧。

[截图:Block 编辑器插入面板里搜到 "Are You Paying Attention?" Block、插入后编辑器内显示的 "Hello, this is from the admin editor screen." 效果]


Hook / Function 速查

名称类型用途
enqueue_block_editor_assetsWP hook只在 Block 编辑器页面触发的资源加载钩子
wp.blocks.registerBlockType(name, config)WP 全局 JS 对象方法注册一个新的 Gutenberg Block 类型
wp.element.createElement(tag, props, children)WP 全局 JS 对象方法WordPress 原生的、不需要额外工具链就能用的 HTML 元素创建方式(本质是 React 的 createElement)

常见坑

  • 依赖数组里漏写 wp-blocks/wp-element——虽然 Block 编辑器页面几乎总是已经加载了这些包,属于「侥幸能用」,但明确声明依赖才是最佳实践,能避免未来 WordPress 内部加载顺序变化导致的意外故障
  • 以为 save 函数返回的内容在前台访问时还会重新执行 JavaScript——实际上只在编辑器里保存那一刻执行一次,结果被序列化成静态 HTML 存进数据库,前台纯粹是显示这段已经生成好的 HTML

延伸 / 后续讲座会用到

直接用 wp.element.createElement() 手写复杂 HTML 结构会很啰嗦,下一讲开始引入 JSX 语法(借助 WordPress 官方提供的 @wordpress/scripts 工具包简化配置),让 Block 的 HTML 结构写起来更接近真实 HTML。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 24, EP135