如何为 WordPress 添加自定义区块

自定义区块是 WordPress 为用户提供的一项个性化定制服务,使用它可以为站点设计自己想要的区块效果。下文中 Block 即指区块。

一、新建 Block

1、新建 block

在 WordPress 插件目录,运行新建 Block 命令(将 my-block-name 替换为你的 Block 名):

cd wordpress/wp-content/plugins
npx @wordpress/create-block my-block-name

2、启动插件

前往 WordPress 仪表盘插件管理页面,启动新建的 my-block-name 插件。

3、效果

完成上述两步后:

  1. 在 wordpress/wp-content/plugins 目录下,会生成一个以 block 命名的文件夹;
  2. 在编辑文章内容时,可以看到新增的 block;

二、自定义 Block

在 block 文件夹下有 3 个重要文件,通过编辑它们,我们可以为这个 block 自定义样式和行为:

  1. src/edit.js:定义编辑 block 时的区块内容;
  2. src/save.js:定义保存 block 时的区块内容;
  3. my-block-name.php:定义与 block 有关的行为。

以下几个关键的概念和模块,在自定义 block 的内容和样式时将被用到。

1、Block 存储结构

Blcok 以以下结构存储在数据库:

<!-- wp:paragraph {"key": "value"} -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->

WordPress 把它称为序列化区块(a Serialized Block):

  • Block 类型被定义在类似 HTML 注释中 ;
  • 中间部分为主要的 HTML 内容;
  • HTML 变量(attributes)以 JSON 形式存储在注释头部。

2、Block Attributes

这是介绍 attributes 的官方文档地址:

Attributes 是 WordPress 用来存储数据的一种形式,它可以为我们提供动态的样式和内容,故而可用来实现动态 Block。使用它分两步:

(一)向 block.json 添加 attributes

在向 block.json 文件内添加我们自定义的 attributes 时,我们主要为它定义:

  1. type:数据类型,如 string、array、object;
  2. source:数据来源,如:
    • “text”表示来自 HTML 的 text 部分;
    • “attribute”表示来自 HTML 元素的 attribute;
    • “html”表示来自 HTML 自身(主要用于 RichText 模块);
    • 值为空表示取自于 block 存储结构里的注释部分;
  3. selector:数据来源的选择器,如 div、button。通过自定义 class,如 td.time,我们可以为每个 attribute 定义自己的选择器;
  4. default:默认值 。
"attributes": {
    "message": {
        "type": "string",
        "source": "text",
        "selector": "div",
        "default": ""
    }
}

(二)在 edit.js 和 save.js 中使用 attributes

通过向 Edit 和 Save 方法传入 attributes 参数,我们可以获取 attribute 值。这个传进来的 attributes 是一个 object 对象,它的 key 是 attribute 名(如 “message”),通过 attributes.message 就可以得到 message 值:

function Edit( { attributes } ) {
    return (
        <p>Message is { attributes.message }.</p>
    )
}
function save( { attributes } ) {
    return (
        <p>Message is { attributes.message }.</p>
    )
}

3、RichText

RichText 是为可编辑的内容准备的,使用它前先要导入:

import { RichText } from '@wordpress/block-editor';

举例:在定义 Edit 区块的时候,假设有一个 table 的 td 标签,我们希望它可编辑。那么就可以用 RichText 这样为它设定:

export default function Edit({ attributes, setAttributes }) {
    return (
        <div {...useBlockProps()}>
            <table>
                <tbody>
                    <tr>
                        <td>时间</td>
                        <RichText
                            tagName="td"
                            className="time"
                            onChange={(val) => setAttributes({ time: val })}
                            value={attributes.time}
                        />
                    </tr>
                </tbody>
            </table>
        </div>
    );
}

除 tagName、className、onChange、value 外,我们还可以在 RichText 定义 placeholder、allowedFormats 等更多标签选项。

4、useBlockProps

在上面例子中,我们可以看到 {…useBlockProps()} 的应用。 这个 useBlockProps 是为包裹自定义 Block 的标签使用的。这个包裹标签对这个自定义区块来说是唯一的,而且必须是原生 DOM 元素,如 <div>,<table>。

如果需要为这个包裹标签定义 HTML attributes,可以在 {…useBlockProps()} 的括号内定义。如:

{...useBlockProps({className: 'my-classname'})}

5、my-block-name.php

我们可以在以 Block 命名的 php 文件中,为 Block 定义 render_callback 行为,即最后 render 到页面的内容:

create_block_my-block-name_block_init() {
    register_block_type(
        plugin_dir_path(__FILE__),
        [
            'api_version' => 2,
            'render_callback' => 'my_render_callback'
        ]
    );
}

my_render_callback 方法中,我们实现自定义的 callback 方法:

function my_render_callback($block_attributes, $content) {
    // return ...{$block_attributes['time']}...;
}

这里传入了两个参数:

  1. $block_attributes:这就是我们前面提到的 block attributes。我们通过 $block_attributes[‘time’] 获取 attribute 值后应用在网页;
  2. $content:这是存储在数据库的 HTML 静态内容。

三、总结

通过以上技术,我们既可以自定义一个静态 Block,也可以自定义一个动态 Block(使用 attributes)。

WordPress 提供了 Block 的更多用法,如用来自定义 Patterns、Templates。更多用法详见 WordPress 官方文档:

评论

发表回复

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