区块功能

对插件文件和区块元数据做出任何更改后,就可以开始添加区块的核心功能了。

通常,这包括通过 Edit 组件在编辑器中添加区块的功能,以及通过 save 函数定义区块如何存储其输出内容。

让我们看看添加区块功能需要做些什么。

添加区块的编辑功能

通常,最好先构建区块的 Edit 组件,这样它就能在编辑器中正常运行。

目前,区块在编辑器中显示的是脚手架文本:“Copyright Date Block – hello from the editor!”,以及脚手架样式。

如果你打开 src 目录中的 edit.js 文件,滚动到导入语句下方,你会看到以下代码:

export default function Edit() {
    return (
        <p { ...useBlockProps() }>
            { __(
                'Copyright Date Block – hello from the editor!',
                'copyright-date-block'
            ) }
        </p>
    );
}

这段代码用于在编辑器中显示区块,也称为 Edit 组件。这里需要注意几点。

首先,该组件返回的内容看起来像一个包含文本的段落标签:

return (
        <p { ...useBlockProps() }>
            { __(
                'Copyright Date Block – hello from the editor!',
                'copyright-date-block'
            ) }
        </p>
    );

这段代码被称为 JSX,它是一种特殊的语法,看起来像 HTML,但实际上是 JavaScript。因此,虽然 <p> 标签可能看起来像典型的 HTML 段落标签,但你可以看到标签内部有一些代码,这些代码被包裹在花括号 {} 中。

花括号用于表示其中的代码应被当作 JavaScript 来求值,并将结果插入到 JSX 中。

学习 JSX 的工作原理超出了本课的范围,但你可以在 React 网站上了解更多关于 JSX 的信息。

在这个阶段,重要的是要注意 Edit 组件返回的代码被包裹在一个单一的容器元素中。这是该组件的父容器,任何 React 组件都必须只返回一个单一的父容器。这意味着你不能返回两个 <p> 标签,或者一个 <p> 标签和一个 <div> 标签,除非确保它们都在一个父容器内。

根据你的代码编辑器,如果你这样做,可能会看到各种红色警告。

其次要注意的是 useBlockProps 函数的使用。这是一个特殊的函数,被称为 React 钩子,用于获取区块的属性。

你会看到 useBlockProps 前面有三个点 ...,这在 JavaScript 中被称为展开语法。它获取对象的属性,并将对象的键值对添加到它所应用的对象上。

因为 useBlockProps 返回一个包含属性和值的对象,使用展开语法将这些属性和值作为属性应用到父容器上。

最后,你会注意到这段脚手架代码使用了 WordPress__() 函数。这是一个特殊函数,允许文本被翻译成不同的语言,也称为国际化。

你可以在 WordPress 开发者文档中阅读更多关于国际化的内容。

现在,更新组件,使其返回更符合区块需求的内容。例如:

return (
    <p { ...useBlockProps() }>
        { __(
            'Copyright',
            'copyright-date-block'
        ) }
        © 2019 - 2024
    </p>
);

对于版权符号,你可以使用 &copy; HTML 实体,它会在渲染时被转换为正确的符号。

如果你好奇为什么符号和年份被渲染在 __() 函数之外,那是因为你只需要让“Copyright”这个词可翻译。

你可能不想硬编码结束日期,所以你可以使用一些 JavaScript 来获取当前年份作为变量,并用该变量替换年份。

export default function Edit() {
    const currentYear = new Date().getFullYear().toString();
    return (
        <p { ...useBlockProps() }>
            { __(
                'Copyright',
                'copyright-date-block'
            ) }
            © 2019 - { currentYear }
        </p>
    );
}

完成更改后,保存文件,让构建运行,或者手动运行构建命令。

当你将区块添加到文章或页面时,你应该会看到区块现在显示了你定义的输出内容。

添加区块的保存功能

下一步是更新区块的保存功能,使其在前端正确渲染。

目前,当你预览区块时,它仍然显示脚手架文本。

save.js 文件中的 save 函数是在编辑器中每次保存区块时运行的。这是存储在数据库 post_content 字段中并在前端渲染的内容。

打开 src 目录中的 save.js 文件,你会看到以下代码:

export default function save() {
    return (
        <p { ...useBlockProps.save() }>
            { 'Copyright Date Block – hello from the saved content!' }
        </p>
    );
}

这与 Edit 组件中的脚手架代码非常相似,但有一些不同之处。

一个不同之处是,只有区块属性的特定子集通过 useBlockProps.save() 应用到父容器上。

这是因为 save 函数只关注与前端相关的属性,而不涉及编辑器。

另一个区别是,父标签内的代码全部写在一行上。

这对块的实际功能基本没有影响,只是展示了编写相同代码的不同方式。有些开发者喜欢将代码拆分成多行,因为这样在某些情况下更易读。

因此,你可以更新 save 函数,使其返回与 Edit 组件相同的内容。

export default function save() {
    const currentYear = new Date().getFullYear().toString();
    return (
        <p { ...useBlockProps.save() }>
            { 'Copyright' } © 2019 - { currentYear }
        </p>
    );
}

一旦更新后的块构建完成,将其添加到文章中并预览。你应该会看到块现在显示了保存后的标记。

其他资源

要了解更多关于构建 Edit 和 save 功能的内容,请查阅块编辑器手册中的 Edit 和 Save 参考指南。

构建你的第一个区块

使用 create-block 搭建好区块框架后,你就可以开始调整代码以满足需求了。

让我们看看在上一课中搭建的版权日期区块具体该如何调整。

清理代码

首先,你可以清理掉不需要的框架代码。

导航到 copyright-date-block/src 目录,删除 view.js 文件。同时,从 block.json 文件中移除 viewScript 属性。请确保 block.json 文件中最后一个属性末尾不要留下多余的逗号。

主插件文件

现在打开插件根目录下的 copyright-date-block.php 文件。

这个文件需要修改的地方不多,可能只需要调整插件头部中的 @package 注释。它默认是 create-block,你可以改成更符合插件的名称。

为了本课的目的,我们将其改为 copyright-date

你还可以改进注册区块的代码,将钩子注册移到 init 钩子的回调函数上方,并简化回调函数名称。

<?php
/**
 * Plugin Name:       Copyright Date Block
 * Description:       Example block scaffolded with Create Block tool.
 * Requires at least: 6.6
 * Requires PHP:      7.2
 * Version:           0.1.0
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       copyright-date-block
 *
 * @package           copyright-date
 */

/**
 * Registers the block using the metadata loaded from the `block.json` file.
 */
function copyright_date_block_init() {
    register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'copyright_date_block_init' );

这样代码会更容易阅读和理解。

如你所见,代码使用 register_block_type 函数注册区块,该函数会利用 block.json 文件中的元数据。

因此,现在是检查 block.json 文件的好时机。

区块元数据

block.json 文件以 JSON 格式包含区块的元数据。

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "create-block/copyright-date-block",
    "version": "0.1.0",
    "title": "Copyright Date Block",
    "category": "widgets",
    "icon": "smiley",
    "description": "Example block scaffolded with Create Block tool.",
    "example": {},
    "supports": {
        "html": false
    },
    "textdomain": "copyright-date-block",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": "file:./style-index.css",
    "viewScript": "file:./view.js"
}

JSON 代表 JavaScript 对象表示法,它是一种轻量级的数据格式,易于人类读写,也易于机器解析和生成。

JSON 由键值对组成,每个值也可以是嵌套的 JSON 对象。

要修改框架生成的区块元数据以适应你的区块,至少需要更改以下属性的值:

  • 更新 name。这里可以将 create-block 替换为与插件头部中 @package 值相同的名称,即 copyright-date
  • 更新 icon。现在将 icon 的值改为 calendar。这个图标来自 Gutenberg 图标库。
  • 更新 description,使其更符合你的区块。

你的 block.json 文件应该类似这样:

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "copyright-date/copyright-date-block",
    "version": "0.1.0",
    "title": "Copyright Date Block",
    "category": "widgets",
    "icon": "calendar",
    "description": "A block that displays the copyright date.",
    "example": {},
    "supports": {
        "html": false
    },
    "textdomain": "copyright-date-block",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": "file:./style-index.css"
}

区块的主 JavaScript 文件

src 目录中的 index.js 文件是区块的主 JavaScript 文件。通常你不需要对这个文件做太多修改,因为它已经设置好用于在区块编辑器中注册区块。

在文件顶部,你会看到以下代码行:

import { registerBlockType } from '@wordpress/blocks';

JavaScript 的 import 声明用于从其他地方导入功能(变量、函数、对象)。

这里,代码从 @wordpress/blocks 包中导入了 registerBlockType 函数,这个包是驱动区块编辑器的核心包。

接下来,它导入了 style.scss 文件,该文件包含区块的样式。

然后它导入了 Edit 组件。这个组件是从 edit.js 文件中导出的。

之后,它导入了 save 函数。这个函数是从 save.js 文件中导出的。

最后但同样重要的是,它将 block.json 文件中的 JSON 对象作为 metadata 变量导入。

最后,它使用 registerBlockType 函数注册区块,并传入两个变量:区块名称和一个包含区块属性的配置对象。

在属性对象内部,edit 属性被设置为 Edit 组件的值,save 属性被设置为 save 函数的值。由于 save 属性和导入的 save 函数同名,因此使用了简写语法来设置属性值。

首次构建

现在你已经更新了一些区块代码,可以首次构建你的区块了。

要构建区块,请打开终端并导航到区块插件目录的根目录。然后运行以下命令:

npm run build

这将扫描 src 目录中的内容,并将该目录中的文件编译到 build 目录中。

如果 build 目录不存在,则会自动创建。

每当您对区块代码进行更改时,都需要再次运行此命令来更新构建目录。

另外,还有一个 npm run start 命令,它会启动一个开发服务器,监视 src 目录中的文件更改,并自动将它们构建到 build 目录中。

npm run start

当您正在积极开发区块时,这个功能非常有用。

无论您使用哪种方式,如果打开 WordPress 仪表盘,创建一篇新文章,并添加您的区块,您应该会在区块插入器中看到该区块。

您会注意到图标已经改变,描述也更具体地针对您的区块。

其他资源

您可以在区块编辑器手册的“block.json 中的元数据”部分了解更多关于区块元数据字段的信息,以及在“开发平台”和“使用 JavaScript 处理区块编辑器”页面中了解开发平台和构建流程的更多内容。

搭建新区块

当你为区块开发安装了必要的工具后,就可以开始开发你的第一个区块了。

在本课中,你将了解一个名为 create-block 的工具,它能让你快速搭建第一个区块插件。你将学习为什么要使用 create-block、如何使用它,并审查它生成的代码。

什么是 create-block?

与任何软件开发项目一样,为 WordPress 开发区块需要以特定方式设置一系列文件和文件夹。

有多种方法可以做到这一点,但你理想的做法是遵循某些最佳实践来构建区块。

Create-block 是一个命令行工具,可帮助你按照这些最佳实践搭建新的区块插件。

在软件开发中,脚手架搭建是指为项目创建基本结构的过程,以便你在此基础上进行构建。

使用 create-block,你可以运行一个终端命令来创建新的区块插件,create-block 会按照区块开发的最佳实践为你设置必要的文件和文件夹。

为什么用插件?

虽然不要求必须将区块作为插件的一部分来开发,但这通常是推荐的做法。

主要原因之一是,提交到 WordPress.org 主题目录的主题中不允许包含自定义区块。

然而,如果你是为自己或客户开发主题,则可以在主题中包含自定义区块,区别在于注册区块的方式不同。

但归根结底,区块开发体验和工具设计为与插件配合使用效果最佳,因此本系列课程将遵循这一方式。

我们要构建什么?

在本系列课程中,你将构建一个“版权日期区块”。

这是一个基础但实用的区块,具有以下功能:

  • 显示文本“Copyright”,后跟版权符号(©),然后是起始年份和当前年份
  • 用户应能调整区块在页面上的对齐方式
  • 它应始终应用以下 CSS:border: 1px solid #111111; padding: 5px;
  • 用户还应能调整起始年份

使用 Create Block

要搭建你的第一个区块,请在本地计算机上打开终端,并切换到本地 WordPress 安装目录的 /wp-content/plugins 目录。

通常通过运行以下命令来完成:

cd /path/to/your/wordpress/wp-content/plugins

然后,运行 create-block 命令,并包含一个插件别名。别名是你想创建的插件的唯一名称。

npx @wordpress/create-block copyright-date-block

如果系统要求确认安装 create-block 包,请输入 y 并按回车键。

这将在 copyright-date-block 目录中创建一个新插件,安装所有必需的包,并创建必要的文件。

一旦新插件搭建完成,你的 WordPress 安装目录中应该会出现一个新的插件文件夹,其名称与你定义的别名一致。

如果你浏览到 WordPress 仪表盘并导航到插件页面,应该会看到你的新插件列在那里。

激活它,一旦激活,创建一篇新文章。

你应该能够在编辑器中添加你新搭建的区块。

搭建好的插件

通过在代码编辑器中打开 copyright-date-block 目录,查看搭建好的区块插件的样子。

首先,有三个目录:

  • build 目录是区块代码最终可部署构建版本所在的位置。这是在编辑器中使用区块时驱动区块的代码。你通常不需要触碰此目录或其任何文件。
  • node_modules 目录是所有 Node.js 包所在的位置。这些也称为项目依赖项,你仅在本地区块开发时需要它们。
  • src 目录是你编写区块代码时花费大部分时间的地方。此目录包含你将用于开发区块的文件。这些文件最终会被编译到 build 目录中的代码中。

在这三个目录之后,还有一些文件。

.editorconfig 文件用于统一不同编辑器和 IDE 的编码风格。

.gitignore 由 Git 版本控制系统使用,用于管理哪些代码提交到版本控制。

这些文件的作用超出了区块开发所需的知识范围,所以如果你不知道它们是做什么用的,暂时可以放心忽略它们。

如果你看不到这两个文件,可能需要在目录浏览器或代码编辑器中启用“显示隐藏文件”功能。

接下来是 copyright-date-block.php 文件。这是启动插件执行的主插件文件。

在该文件中,你会看到标准的插件头部信息以及用于注册区块的 PHP 代码。

这里,copyright_date_block_copyright_date_block_block_init 函数调用了 register_block_type() 函数,并将前面提到的 build 目录的路径作为参数传入。

这个函数随后被挂载到 init 动作上。

接下来,你会看到 package-lock.json 文件和 package.json 文件。

package.json 文件是 npm 在开发 JavaScript 项目时使用的文件。

{
    "name": "copyright-date-block",
    "version": "1.0.0",
    "description": "Example block scaffolded with Create Block tool.",
    "main": "index.js",
    "scripts": {
        "build": "wp-scripts build",
        "format": "wp-scripts format",
        "lint:css": "wp-scripts lint-style",
        "lint:js": "wp-scripts lint-js",
        "packages-update": "wp-scripts packages-update",
        "plugin-zip": "wp-scripts plugin-zip",
        "start": "wp-scripts start"
    },
    "devDependencies": {
        "@wordpress/scripts": "^27.9.0"
    }
}

它包含了项目的关键信息,包括可以在项目上运行的任何脚本以及所有依赖项。

依赖项是你的项目正常运行所需的外部包或模块。就区块开发而言,你需要的依赖项是 @wordpress/scripts 包的开发依赖项。这些依赖项会被安装到你的 node_modules 目录中。

scripts 对象包含了一系列可以在开发过程中运行的命令行脚本。其中最重要的有:

  • build:将 src 目录中的文件编译到 build 目录中
  • start:启动一个开发服务器,监视 src 目录中文件的变化,并自动将它们编译到 build 目录中

当你开始开发区块时,会学习如何使用这些脚本。

package-lock.json 文件包含了所有已安装依赖项的列表,以及所使用的依赖项的版本号。它将所需的依赖项锁定到此文件中指定的版本号。这是另一个你现在可以忽略的文件。

最后,还有一个 readme.txt 文件,只有当你打算将插件发布到 WordPress 插件目录时,才需要编辑它。

src 目录

你所有的区块开发工作都在 src 目录中进行。让我们看看生成了哪些文件:

  • block.json 以 JSON 对象的形式存储区块的元数据。你可以在区块元数据手册页面中了解更多关于区块元数据的信息。此文件允许你定义区块名称、标题、图标、组成区块的各种文件等等。
  • edit.js 是你在开发区块时花费大部分时间的地方。此文件导出一个 React Edit() 组件,该组件在编辑器中渲染,并决定区块在编辑器中的外观和功能。
  • editor.scss 包含控制区块在区块编辑器中外观的样式。通常,你会希望区块在编辑器中的外观与网站前端一致,因此你通常根本不需要此文件。
  • index.js 是区块 JavaScript 执行的起点。它设置并执行 registerBlockType 函数,以在编辑器中注册区块。
  • save.js 导出一个 save() 函数,该函数决定在保存文章或页面时将保存到 wp_posts 表中 post_content 字段的标记,因此也决定了区块在前端的外观和功能。
  • style.scss 包含控制区块在编辑器和前端外观的样式。如果你需要区块在编辑器中显示不同,此处的样式可以被 editor.scss 中的样式覆盖。
  • view.js 是一个用于在前端为区块添加任何额外 JavaScript 的文件。这是另一个你通常不需要的文件。

build 目录

在开发过程中,你将执行之前在 package.json 文件中看到的脚本,将 src 目录中的文件编译到 build 目录中。

构建区块代码的过程,也称为打包代码,是将区块代码转换为所有浏览器兼容格式的过程。

当你生成区块脚手架时,create-block 工具也运行了构建过程,为你生成了 build 目录。

你会注意到,有些文件(如 block.json 文件)会原样打包到 build 目录中,而其他文件(如 index.js 文件)则会被转换。还有一些额外的文件,如 index.asset.php 文件,是在构建过程中生成的。

当 WordPress 在编辑器或前端加载你的区块时,它执行的是来自 build 目录中的代码。

package.json 文件中定义为开发依赖的 @wordpress/scripts 包,使用一个名为 Webpack 的工具来打包你的区块代码。

关于其工作原理的细节超出了本课程的范围,但你可以在 Webpack 文档中了解更多信息。

附加资源

要了解更多关于 create-block 工具及其提供的所有不同选项,请查看区块编辑器手册中关于 create-block 的包参考文档。

搭建区块开发环境

WordPress 区块是 WordPress 网站存储和展示内容的默认方式。

让我们快速了解一下什么是区块、它们如何工作,以及开始开发它们需要什么。

WordPress 区块

区块在创建和编辑内容时用于文章和页面编辑器,以及在创建和编辑主题模板或模式时用于站点编辑器。

在底层,区块由一种特定格式的 HTML 注释组合而成,该注释定义了区块,如果需要,还会使用 HTML 实体来表示区块内容。

区块的结构

让我们看一个文章中区块的示例。

在你的本地 WordPress 安装中,创建一个新文章,给它一个标题,并在文章编辑器中输入一些文本。

然后,点击文章右上角的选项图标,选择代码视图。

<!-- wp:paragraph -->
<p>Hello World</p>
<!-- /wp:paragraph -->

如你所见,HTML 段落标签被包裹在名为 wp:paragraph 的 HTML 注释中。这些 wp:paragraph 注释是 WordPress 识别这是一个段落区块的方式。区块的实际内容是 wp:paragraph 标签内的所有内容,在这个例子中,就是 HTML 段落标签及其内部的内容。

现在点击“退出代码编辑器”,在侧边栏中,为区块应用一个背景颜色。

现在切换回代码视图,注意 wp:paragraph 标签包含了一些额外的数据。

<!-- wp:paragraph {"backgroundColor":"luminous-vivid-amber"} -->
<p class="has-background has-luminous-vivid-amber-background-color">Hello World</p>
<!-- /wp:paragraph -->

backgroundColor 属性以一种称为 JSON 的特殊格式添加到区块包装器中。当这篇文章在前端渲染时,WordPress 会将其转换为一个 CSS 类,应用到区块上。

准备工作

除了你的本地 WordPress 安装和代码编辑器之外,你还需要一些额外的工具来开发区块。

你需要一个终端来运行命令。

并且你需要安装 Node.js 和 npm。

关于终端的一切

你首先需要的是访问终端来运行命令。

终端是一种允许你使用文本命令与计算机交互的工具。它也被称为命令行或命令提示符。你的操作系统将决定终端的外观以及你可以使用哪些命令。

在 macOS 上,默认的终端称为 Terminal,位于你的应用程序 -> 实用工具文件夹中。你也可以通过点击 Launchpad 应用并搜索 Terminal 来启动它。

在大多数 Linux 发行版上,默认的终端也称为 Terminal,通常位于应用程序菜单中。

在 Windows 上,默认的终端称为命令提示符,位于开始菜单中。

然而,我们推荐在 Windows 上使用名为 PowerShell 的终端应用程序,因为可以配置 PowerShell 使其工作方式类似于 MacOS 和 Linux 上的终端。

某些 Windows 版本确实预装了 PowerShell,但我们推荐安装来自 Microsoft 网站的版本。要下载 PowerShell,请访问 https://learn.microsoft.com/en-gb/powershell/,点击下载 Powershell 按钮,并安装你下载的可执行文件。

安装完成后,你可以通过在开始菜单中搜索 PowerShell 来启动它。

一旦你有了一个可用的终端,你将能够安装开始开发区块所需的软件。

Node.js 和 npm

区块开发依赖于一个名为 React 的 JavaScript 框架。要使用 React,你需要在本地计算机上安装 Node.js 和 npm。

安装 Node.js

由于 npm 与 Node.js 捆绑在一起,你只需要安装 Node.js 即可开始使用。

虽然有多种方法可以安装带有 npm 的 Node.js,但我们推荐使用一个名为 nvm 的工具,它代表 Node 版本管理器。

你可以在 github.com/nvm-sh 找到关于 nvm 的详细信息。

这将使你能够根据所使用软件的要求,安装和使用不同版本的 Node.js。

在 MacOS 和 Linux 上安装 NVM

如果你使用 MacOS 或 Linux,你可以打开默认的终端应用程序,并通过运行 nvm 安装脚本来安装 nvm,你可以从 nvm 文档中复制该脚本。

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

安装完成后,你可以使用 nvm install 命令来安装你需要的 Node.js 和 npm 版本。

在 Windows 上安装 NVM

如果你使用的是 Windows 机器,你可以通过 Windows 的 Chocolatey 包管理器(特别是 Chocolatey CLI)来安装 nvm。

首先,右键点击 Powershell 菜单项,选择“以管理员身份运行”,以管理员权限打开 Powershell。

浏览到 Chocolatey CLI 安装文档,向下滚动到使用 PowerShell 安装说明部分。

复制这些说明,然后在 Powershell 窗口中右键点击以粘贴它们。

Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

按回车键运行该命令。

一旦 Chocolatey CLI(也称为 choco)安装完成,使用以下命令安装 nvm。

choco install -y nvm

nvm 安装完成后,使用 nvm install 命令安装所需的 Node.js 和 npm 版本。

NVM 的使用

在录制本教程时,Node.js 当前的稳定 LTS(长期支持)版本是版本 20,但请查看 Node.js 网站,确认在您安装 Node.js 时是否有更新的版本。

如果当前 LTS 版本高于 20,您可以在以下命令中替换为该版本号。

要安装 Node.js 和 npm,请使用 nvm install 命令,并指定您要安装的版本号。

nvm install 20

也可以通过运行以下命令来安装最新的 LTS 版本。

nvm install --lts

然后,您可以运行 nvm list 来查看已安装的 Node.js 版本。

nvm list

由于 nvm 允许您运行多个版本的 Node.js,您需要告诉 nvm 您要使用哪个版本。可以通过运行 nvm use 命令,后跟版本号来实现。

nvm use 20

这会将当前终端实例的 Node.js 版本设置为版本 20。

此外,还可以使用 LTS 选项运行 npm use 命令。

nvm use --lts

最后,如果您确实安装了多个版本的 Node.js 和 npm,可以通过运行 nvm alias default 命令来设置默认使用的版本。

nvm alias default 20

然后,通过运行以下命令检查已启用的 Node.js 和 npm 版本。

node -v
npm -v

如果您正在处理多个需要不同 Node.js 和 npm 版本的项目,这将非常有用。

现在您已拥有所有必需的工具,可以开始您的区块开发之旅了。

其他资源

WordPress 开发者文档中有一个专门介绍区块编辑器的部分,其中包含大量关于区块、区块开发以及区块开发者可用的各种包的信息。

阅读“区块开发基础”部分也是一个好主意,以便更好地理解整个过程。

加载CSS或JavaScript

由于插件不控制 WordPress 网站的外观和感觉,如果你需要使用自定义 CSS 或 JavaScript,你需要遵循一个称为“入队”的过程。

为了添加自定义 CSS 或 JavaScript,WordPress 插件需要一种方法,在任何时候将脚本或样式标签添加到正在渲染的 HTML 中。

幸运的是,WordPress 允许插件开发者将其插件的 CSS 或 JavaScript 入队,这样它就会被添加到任何文章或页面请求的 HTML 中的正确位置。

在本课中,你将学习如何在前端或管理仪表板上入队自定义 CSS 和 JavaScript。

入队 CSS

与大多数 WordPress 功能一样,首先你需要在特定钩子上注册一个回调函数,并使用该回调函数来入队你的脚本或样式。

要使用的正确钩子是 wp_enqueue_scripts 动作钩子。从文档中可以看到,尽管钩子名称如此,但它用于入队脚本和样式。

因此,首先在钩子上注册回调函数,并创建回调函数。

<?php
add_action( 'wp_enqueue_scripts', 'bookstore_enqueue_scripts' );

function bookstore_enqueue_scripts() {
    // 在这里入队脚本或样式
}

现在你可以入队自定义 CSS 或 JavaScript 了。

让我们针对前端任何给定书籍的标题,并将其变为红色。

继续在你的 bookstore 插件目录中创建一个空的 bookstore.css 文件,以便你的插件将其入队。

在该文件中,添加以下代码:

body.single-book h1 {
    color: red;
}

每当渲染单本书籍时,它都会将 single-book 类添加到 HTML 页面的 body 元素中,因此这段代码会将 body 标签内任何 h1 标签的颜色更改为红色。

现在你已经创建了 CSS 文件,需要在 bookstore_enqueue_scripts() 函数中将其入队。

你可以使用 wp_enqueue_style 函数来实现这一点。

至少,你需要向该函数传递前两个参数:

  • 句柄(handle),这是样式表的唯一名称,在样式表添加到 HTML 时使用
  • 源路径(src),即样式表的完整 URL,或相对于 WordPress 根目录的样式表路径。

对于插件,你可以使用 plugins_url 函数获取插件目录的 URL,然后将其与 CSS 文件的路径拼接起来。

<?php
function bookstore_enqueue_scripts() {
    wp_enqueue_style( 'bookstore', plugins_url( 'bookstore.css', __FILE__ ) );
}

WordPress 请求期间,这会将样式表句柄和 URL 添加到一个 wp_styles 对象中。

当生成要渲染的 HTML,并且 WordPress 准备输出 head 标签时,它会遍历 wp_styles 对象中的每个样式表,并输出一个 HTML 样式元素,将句柄作为元素的 id 属性,将源路径作为元素的 href 属性。

入队此 CSS 文件后,继续浏览你添加的任何书籍的单本书籍视图,你应该会注意到 h1 元素是红色的。

入队 JavaScript

你也可以使用相同的 wp_enqueue_scripts 动作钩子回调函数,从你的插件入队 JavaScript 文件。

唯一的区别是,你可以使用 wp_enqueue_script 而不是 wp_enqueue_style

wp_enqueue_style 类似,你需要向 wp_enqueue_script 传递唯一的句柄和源路径参数,以便它入队你的 JavaScript 文件。

首先,在 bookstore 目录中创建一个 bookstore.js 文件,并向其中添加一个简单的 JavaScript 警告框。

alert( 'Hello from Bookstore' );

现在,更新 bookstore_enqueue_scripts 函数,使用 wp_enqueue_script 入队 bookstore.js 文件。

<?php
function bookstore_enqueue_scripts() {
    wp_enqueue_style( 'bookstore', plugins_url( 'bookstore.css', __FILE__ ) );
    wp_enqueue_script( 'bookstore', plugins_url( 'bookstore.js', __FILE__ ) );
}

与样式表一样,wp_enqueue_script 会将脚本句柄和 URL 添加到一个 wp_scripts 对象中,并为每个脚本输出一个 HTML 脚本元素,在 id 属性中使用句柄,在 src 属性中使用 URL。

入队此脚本后,浏览你添加的任何书籍的单本书籍视图,你应该会看到页面上弹出警告框。

在管理仪表板上入队

你也可以在管理仪表板上入队样式和脚本,使用 admin_enqueue_scripts 动作钩子而不是 wp_enqueue_scripts 动作钩子。

<?php
add_action( 'admin_enqueue_scripts', 'bookstore_admin_enqueue_scripts' );

function bookstore_admin_enqueue_scripts() {
    // 在这里入队管理仪表板的脚本或样式
}

一旦你在钩子上注册了回调函数,入队脚本和样式的过程与前端相同,使用 wp_enqueue_stylewp_enqueue_script

选择性入队

在本课的示例中,bookstore CSS 和 JavaScript 在网站的每个页面上都被入队。这并不理想。例如,对于 CSS,它专门针对单本书籍视图上的 h1 元素,因此你不需要为除书籍之外的任何内容入队 CSS。

可以进行选择性入队,即你确定文件应该被入队的具体场景。

例如,在 bookstore.css 的情况下,你可以使用 WordPress 的 is_singular() 函数来检查当前渲染的内容是否为书籍自定义文章类型。

如果不是,则退出函数,不加载样式表或脚本文件。

add_action( 'wp_enqueue_scripts', 'bookstore_enqueue_scripts' );
function bookstore_enqueue_scripts() {
    if ( ! is_singular( 'book' ) ) {
        return;
    }
    wp_enqueue_style(
        'bookstore-style',
        plugins_url() . '/bookstore/bookstore.css'
    );
    wp_enqueue_script(
        'bookstore-script',
        plugins_url() . '/bookstore/bookstore.js'
    );
}

还有其他多种方法可以确保你的插件样式表或脚本文件仅在需要时加载。这样做意味着你的插件不会给任何安装了它的 WordPress 站点增加不必要的开销或加载时间。

自定义文章类型数据

有时候,默认的自定义文章类型字段可能不够用,你需要在一个自定义文章类型上存储额外的数据。

幸运的是,WordPress 支持一种叫做文章元数据的功能,它允许你存储关于文章的额外信息。

让我们看看如何在一篇文章或自定义文章类型上使用文章元数据。

什么是文章元数据

文章元数据是一种在 WordPress 数据库中存储文章额外信息的方式。

文章元数据以键值对的形式存储在 postmeta 表中。如果你查看 WordPress 数据库中的 postmeta 表,你会看到它有四个列:meta_idpost_idmeta_keymeta_value

post_id 是元数据关联的文章的 ID。meta_key 是元数据字段的名称,meta_value 是它的值。

添加文章元数据

你可以使用 add_post_meta 函数向文章添加文章元数据。这个函数接受三个参数:文章的 ID、元数据的名称和元数据的值。

假设你想向 ID 为 1 的文章添加一个文章元数据字段,并且你想将文章撰写地点存储为 London

你可以使用以下代码:

<?php add_post_meta( 1, 'location', 'London' ); ?>

还有其他用于处理文章元数据的函数,例如 update_post_metadelete_post_metaget_post_meta

你可以在插件开发者手册的元数据页面中阅读更多关于这些函数以及如何在插件中使用它们的内容。

自定义字段面板

通过代码添加文章元数据是一种方式,但也可以让站点管理员通过 WordPress 管理界面添加文章元数据。

其中一种方法是使用文章类型的自定义字段面板。

要启用自定义字段面板,你首先需要确保你的自定义文章类型支持元数据。

为此,你需要添加或更新 supports 参数,以包含对 custom-fields 的支持。

然后,在编辑自定义文章类型时,点击编辑器的选项图标,选择偏好设置,点击面板,并启用自定义字段开关。

这将刷新编辑器,你会在屏幕底部看到自定义字段面板。

在这里,你可以添加一个新的自定义字段,并为其指定名称和值。

例如,如果你想添加一本书的 ISBN 号,你可以添加一个名为 isbn 的自定义字段,并将值设为 ISBN 号。

这个面板使用 add_post_meta 函数将元数据添加到文章中。

为自定义字段面板预填充字段名称

也可以使用预定义的元字段列表来填充自定义字段面板的名称字段。

为此,你需要挂钩到 postmeta_form_keys 过滤器,并添加你想要在自定义字段面板中显示的元字段名称。

postmeta_form_keys 过滤器在自定义字段面板的 HTML 渲染之前触发,并传递两个参数:一个元键数组和文章对象。

如果没有定义其他键,则会执行一个查询来获取文章任何现有元数据的键。

因此,通过更新元键数组,你可以将元字段键添加到自定义字段面板,从而使用户更容易添加正确的元数据。

以下是一个如何实现此操作的示例:

add_filter( 'postmeta_form_keys', 'add_isbn_to_custom_fields', 10, 2 );

function add_isbn_to_custom_fields( $keys, $post ) {
    if ( 'book' === $post->post_type ) {
        $keys[] = 'isbn';
    }
    return $keys;
}

你将一个回调函数注册到 postmeta_form_keys 过滤器上,并将接受的参数设置为 2,以接受过滤器中的两个参数。

然后,检查文章类型是否为 book,如果是,则将 isbn 选项添加到 $keys 数组中,然后返回该数组。

如果文章类型是 book,它就会将 isbn 元字段添加到自定义字段面板中。

如果你创建或编辑一本 book,并且启用了自定义字段面板,你会看到 isbn 字段可用于向文章添加元数据。

自定义元数据框

另一种允许站点管理员添加文章元数据的方法是使用自定义元数据框。

然而,使用自定义元数据框还需要充分理解安全开发的原则,但现在你可以在插件开发者手册的自定义元数据框页面中阅读相关内容。

你将在插件开发者学习路径中学习如何使用元数据框。

自定义分类法

在 WordPress 中,分类法是一种将内容分组的方式。在默认的 WordPress 安装中,有两种已注册的分类法:分类目录和标签。

当开发一个注册自定义文章类型的插件时,你也可以注册自定义分类法。

这为你的插件增加了额外的灵活性,因为它允许你的自定义文章类型独立于默认的分类目录或标签进行分组。

让我们看看这是如何工作的,以及你需要做什么来注册一个自定义分类法。

为什么要使用自定义分类法?

你可能会认为 WordPress 自带的两种自定义分类法已经足够,但有时你的插件可能需要以不同的方式对数据进行分组。

例如,在一个书店中,你可能希望按类型对书籍进行分组,比如小说、非小说、科幻小说等。

此外,当你为特定文章类型注册自定义分类法时,该分类法将仅对该文章类型可用,并会在管理菜单和编辑界面中与该文章类型关联显示。

注册自定义分类法

让我们为你之前课程中构建的书店插件添加一个自定义分类法:

<?php
/**
 * 插件名称:书店
 * 描述:一个管理书籍的插件
 * 版本:1.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // 如果直接访问则退出
}

add_action( 'init', 'bookstore_register_book_post_type' );
function bookstore_register_book_post_type() {
    $args = array(
        'labels' => array(
            'name' => '书籍',
            'singular_name' => '书籍',
        ),
        'public' => true,
        'has_archive' => true,
        'show_in_rest' => true,
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'custom-fields' ),
    );

    register_post_type( 'book', $args );
}

要注册自定义分类法,你可以使用 register_taxonomy 函数,其方式与 register_post_type 函数类似。

这个函数要求你传入分类法的名称、分类法关联的文章类型以及一个参数数组。

register_post_type 函数类似,register_taxonomy 函数也需要挂载到 init 动作上。

所以首先注册该动作的回调函数。

add_action( 'init', 'bookstore_register_genre_taxonomy' );

然后,你可以创建 bookstore_register_genre_taxonomy 回调函数。

在这个函数中,创建参数数组,并调用 register_taxonomy 函数,传入相关参数来创建分类法。

function bookstore_register_genre_taxonomy() {
    $args = array(
        'labels'       => array(
            'name'          => '类型',
            'singular_name' => '类型',
            'edit_item'     => '编辑类型',
            'update_item'   => '更新类型',
            'add_new_item'  => '添加新类型',
            'new_item_name' => '新类型名称',
            'menu_name'     => '类型',
        ),
        'hierarchical' => true,
        'rewrite'      => array( 'slug' => 'genre' ),
        'show_in_rest'           => true,
    );

    register_taxonomy( 'genre', 'book', $args );
}

你也可以将此代码添加到 bookstore_register_book_post_type 函数中,这样在注册书籍文章类型时,类型分类法也会被注册。

一旦将其添加到你的书店插件中,你会在管理菜单中看到一个新的“类型”菜单项,并且能够为你的书籍添加类型。

此外,一旦你添加了一些类型,在添加或编辑书籍时,你就可以从这些类型中进行选择。

就像常规分类法一样,你将能够浏览每个分类法的归档页面,并查看所有与该分类法关联的书籍。

进一步阅读

要了解更多关于自定义分类法及其注册方法,请访问插件开发者手册中的分类法页面。

同时,建议阅读 WordPress 开发者文档中完整的 register_taxonomy 函数参考页面,其中包含所有可以传递给该函数的参数及其作用的完整列表。

自定义文章类型

开发自定义插件的一个常见用途是利用 WordPress 文章 API 来创建自定义文章类型。

构建在线书店

假设你正在构建一个在线书店,并且想要存储待售书籍的数据。

WordPress 核心文章 API 允许你注册自定义文章类型。这些自定义文章类型扩展了核心的 post 数据类型,该类型存储在 WordPress 数据库的 posts 表中。

自定义文章类型的一个例子是 page 数据类型,它由 WordPress 核心注册。

使用 WordPress 文章 API,你可以创建一个自定义文章类型来存储书籍信息。

当你正确注册自定义文章类型时,WordPress 会自动为你的自定义文章类型创建一个新的管理菜单项,以及用于管理数据的管理页面。

自定义文章类型

要注册自定义文章类型,你需要使用 WordPress 的 register_post_type 函数。

WordPress 开发者文档中的函数参考页面可以看出,这个函数接受两个参数:自定义文章类型的名称,以及一个定义自定义文章类型的参数数组。

参数是你在函数定义中定义的变量名称。在这个例子中,参数是作为字符串变量的名称和一个参数数组。

当你使用这个函数时,你传入这些参数的值。这些值被称为参数值。

下面是一个创建参数数组并调用 register_post_type 函数,传入相关参数值来创建书籍自定义文章类型的示例。

$args = array(
    'labels' => array(
            'name'          => '书籍',
            'singular_name' => '书籍',
            'menu_name'     => '书籍',
            'add_new'       => '添加新书',
            'add_new_item'  => '添加新书',
            'new_item'      => '新书',
            'edit_item'     => '编辑书籍',
            'view_item'     => '查看书籍',
            'all_items'     => '所有书籍',
    ),
    'public' => true,
    'has_archive' => true,
    'show_in_rest' => true,
    'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt' ),
);

register_post_type( 'book', $args );

让我们看看如何在插件中实现这段代码。

实现书籍自定义文章类型

首先,按照你在“什么是插件”课程中学到的方式创建一个新插件。

wp-content/plugins 目录中添加一个名为 bookstore 的目录。

然后在该目录中创建一个名为 bookstore.php 的新 PHP 文件。

在文件中,添加 PHP 开始标签和插件头部信息到文件顶部,同时添加 ABSPATH 检查以防止直接访问文件。

<?php
/**
 * 插件名称: Bookstore
 * 插件描述: 一个用于管理书籍的插件
 * 版本: 1.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // 如果直接访问则退出
}

接下来,创建一个名为 bookstore_register_book_post_type 的函数,用于注册自定义文章类型。创建参数数组,然后调用 register_post_type 函数,传入相关参数值来创建书籍自定义文章类型。

function bookstore_register_book_post_type() {
     $args = array(
        'labels' => array(
            'name'          => '书籍',
            'singular_name' => '书籍',
            'menu_name'     => '书籍',
            'add_new'       => '添加新书',
            'add_new_item'  => '添加新书',
            'new_item'      => '新书',
            'edit_item'     => '编辑书籍',
            'view_item'     => '查看书籍',
            'all_items'     => '所有书籍',
        ),
        'public' => true,
        'has_archive' => true,
        'show_in_rest' => true,
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt' ),
    );

    register_post_type( 'book', $args );
}

注意函数名中使用了 bookstore_ 前缀。

这是为函数名添加前缀以避免与其他插件或主题冲突的一个例子。

你可以在插件开发者手册的插件最佳实践页面中了解更多关于此方法以及其他防止函数冲突的方法。

最后一步是调用 bookstore_register_book_post_type 函数。你需要将其挂载到 init 动作上才能实现。

如果你跳过了关于 WordPress 钩子的模块,钩子是一种在 WordPress 请求生命周期中的特定点运行代码的方式。

add_action( 'init', 'bookstore_register_book_post_type' );

你的最终代码应该如下所示:

<?php
/**
 * 插件名称:书店
 * 描述:一个用于管理书籍的插件
 * 版本:1.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // 防止直接访问
}

add_action( 'init', 'bookstore_register_book_post_type' );
function bookstore_register_book_post_type() {
    $args = array(
        'labels' => array(
            'name'          => '书籍',
            'singular_name' => '书籍',
            'menu_name'     => '书籍',
            'add_new'       => '添加新书',
            'add_new_item'  => '添加新书',
            'new_item'      => '新书',
            'edit_item'     => '编辑书籍',
            'view_item'     => '查看书籍',
            'all_items'     => '所有书籍',
        ),
        'public' => true,
        'has_archive' => true,
        'show_in_rest' => true,
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt' ),
    );

    register_post_type( 'book', $args );
}

现在,进入你的 WordPress 仪表盘并激活该插件。

你应该会在管理菜单中看到一个新的菜单项“书籍”,并且能够为你的自定义书籍文章类型添加新书。

如果你浏览 WordPress 数据库中的 wp_posts 表,会看到一个新行,其中 post_type 列设置为 book,并包含新书的数据。

自定义文章类型与性能

需要注意的是,注册过多的自定义文章类型可能会对 WordPress 网站的性能产生影响。

这是因为自定义文章类型的注册过程会在每次网站请求时执行,即使该页面并未使用该自定义文章类型。

因此,要谨慎使用自定义文章类型,并考虑何时使用它们,何时创建自定义表来存储自定义数据。

你可以在插件开发者手册的“使用插件创建表”页面中了解更多关于创建和使用自定义表的信息。

在插件开发者学习路径中,你也会学到更多相关内容。

进一步阅读

要了解更多关于自定义文章类型及其注册方法,请访问插件开发者手册中的“文章类型”页面。

同时,建议阅读 WordPress 开发者文档中完整的 register_post_type 函数参考页面,其中包含所有可传递给该函数的参数及其作用的完整列表。

插件要求

现在你已经知道什么是插件了,接下来我们来探索创建插件需要什么。

创建你的第一个插件

一个有效的 WordPress 插件最低要求是至少有一个 PHP 文件,即主插件文件,并包含一个开头的 PHP 标签。

在主插件文件内部,第一段代码应该是插件头部信息(Plugin Header),这是一个 PHP 注释块。至少需要包含一个插件名称字段。

要创建你的第一个插件,请导航到 wp-content/plugins 目录,并创建一个名为 example-plugin.php 的 PHP 文件。

cd wp-content/plugins && touch example-plugin.php

在文件内部,确保打开 PHP 标签,这样服务器才能执行 PHP 代码。

<?php

现在,在文件顶部、PHP 开始标签下方添加以下代码。

/**
 * Plugin Name: 示例插件
 */

这就是所谓的插件头部信息,它使用 PHP 注释语法的一种变体——DocBlock 来编写。

要了解更多关于 PHP 注释的内容,请查阅 PHP 手册基本语法部分中的注释页面。

创建好你的第一个插件后,现在可以浏览 WordPress 仪表盘中的“插件”页面,你会看到你的插件已经可用并准备激活。

这个插件目前还没有任何功能,但它已经准备好添加功能了。

WordPress 如何识别和存储已激活的插件

一旦插件被激活,它就会被添加到存储在选项表(options table)中序列化数组里的已激活插件列表中。你可以通过在 phpMyAdmin 中运行以下 SQL 查询来找到这个数组。

SELECT * FROM `wp_options` WHERE `option_name` LIKE 'active_plugins'

注意它如何存储 PHP 文件的文件名。这也被称为插件别名(plugin slug),WordPress 在执行过程中通过它来识别你的插件。

如果你将主插件文件移动到一个目录内,插件别名会发生变化,包含目录名称。

wp-content/plugins 中创建一个名为 example-plugin 的新目录,并将你的插件文件移动到该目录中。

如果你浏览 WordPress 仪表盘中的“插件”页面,你会看到该插件不再处于激活状态,因为别名已经改变了。

你还会注意到“插件”页面顶部有一条警告信息:

插件 example-plugin.php 因错误而被停用:插件文件不存在。

现在激活该插件。

然后返回并查看 wp_options 表中的已激活插件列表,看看新的别名(包含目录名称)是如何被添加到序列化数组中的。

插件头部信息字段

虽然插件名称字段是有效插件的基本要求,但还有额外的字段可以添加到插件头部信息中。

通常建议在插件头部信息中添加描述和版本号。这可以让用户获得更多关于你插件的信息,并且在插件列表中显示效果更好。

/**
 * Plugin Name: 示例插件
 * Description: 这是为 WordPress 开发者路径提供的示例插件。
 * Version: 1.0
 */

你可以在插件开发者手册的头部信息要求页面中查看完整的插件头部信息字段列表。

插件最佳实践

插件手册中还包含一个关于开发插件时常见最佳实践的章节。

其中一个建议是包含一个检查,确保插件代码仅在作为 WordPress 请求的一部分时执行。

if ( ! defined( 'ABSPATH' ) ) {
    exit; // 如果直接访问则退出
}

这段代码的作用是检查 ABSPATH 常量是否已定义,这是一个 WordPress 特有的常量。如果未定义,则退出插件的代码执行。

这样,如果有人试图直接在浏览器中浏览主插件文件,插件中的任何 PHP 代码都不会被执行,从而防止安全风险。

你可以在插件开发者手册的最佳实践页面中了解更多关于此建议及其他建议的信息。

什么是插件?

欢迎来到 WordPress 插件开发入门指南。

什么是插件?

WordPress 插件是一组代码包,可以安装在 WordPress 网站上,用于添加新功能或特性。

主题用于控制 WordPress 网站的外观和感觉,而插件则用于增加或扩展其功能。

为什么要使用插件?

作为 WordPress 开发者,你经常需要为 WordPress 网站创建自定义功能。

虽然可以将这些功能添加到主题或子主题的 functions.php 文件中,但通常将这些代码添加到 WordPress 插件中更合理。

这是因为插件可以独立激活或停用,而不会影响主题。

不仅如此,同一个插件还可以在多个网站上使用。

WordPress 插件目录

WordPress 插件目录包含超过五万个插件,可以安装在 WordPress 网站上。

这些插件可以将 WordPress 网站变成在线商店、社交网络、学习管理系统等等。

WordPress 插件的结构

插件目录中的大多数 WordPress 插件由多个文件组成,但要创建一个有效的插件,你实际上只需要一个主 PHP 文件,并在该文件顶部添加一个特定格式的注释块,也称为 DocBlock。

安装后,插件位于 WordPress 网站的 wp-content/plugins 目录中。

Hello Dolly 是 WordPress 最早的插件之一,它是一个单文件插件的例子。该插件的所有功能都包含在一个名为 hello.php 的 PHP 文件中。

Akismet 是 WordPress 的一个反垃圾插件,它是一个多文件插件的例子。这里的 akismet 目录包含了该插件的所有文件。插件的主文件是 akismet.php,它负责加载所有其他必需的文件。

插件开发者手册

WordPress 插件开发者手册是学习如何创建 WordPress 插件的绝佳资源。它包含如何创建插件、如何使用各种 WordPress API,以及如何将插件提交到 WordPress 插件目录的信息。

你可以通过访问 developer.wordpress.org 并点击页面顶部的“插件”链接来找到插件开发者手册。