构建自定义古腾堡区块:权威WordPress区块开发教程

许多人抱怨开始构建古腾堡区块和应用程序的障碍。学习曲线陡峭,主要是由于开发环境的安装和配置困难。此外,扎实的JavaScript、Node.js、React和Redux知识是这个相当复杂的秘诀的必备要素。

官方的WordPress区块编辑器手册为开发人员提供了大量信息,但您可能会发现自己迷失在这些细节的海洋中。

值得一提的是,Gutenberg项目的首席架构师Matías Ventura在接受WP Tavern采访时所报告的内容:

虽然有些人可以快速学习它,但这对人们来说仍然是一个很大的障碍。我认为这有几个层次;文档在组织和演示方面可能要好一个数量级。我希望我们可以在那里做更多的事情。

考虑到这一点,我们决定提供一个分步教程,旨在帮助我们的读者开始使用Gutenberg区块开发

  1. 古腾堡区块开发先决条件
  2. 什么是古腾堡区块?
  3. 设置您的WordPress开发环境
  4. 初学者区块脚手架的演练
  5. 项目:建造你的第一个古腾堡区块

古腾堡区块开发先决条件

对于本教程,唯一需要的技能是对WordPress插件开发有很好的了解,并且至少对HTML、CSS、JavaScript和React有基本的了解。

这会是一个雄心勃勃的项目吗?你打赌它会的!

在完整性和简单性之间找到正确的折衷方案或决定包含哪些主题和省略哪些主题并不容易。

希望中高级读者能原谅我们没有深入研究某些概念,例如React状态Redux存储高阶组件等。这些主题需要额外的空间和注意力,并且可能对于开始区块开发来说太高级了(除非您是 React 开发人员)。

出于同样的原因,我们不会涵盖与Gutenberg区块开发相关的一些更高级的主题,例如动态区块元框

有了本文结尾您将获得的知识,您将能够立即开始享受乐趣并提高工作效率。

一旦您开始构建区块,您将准备好进一步提高您的技能并自行构建更高级的古腾堡区块。

什么是古腾堡区块?

自2018年12月首次发布以来,区块编辑器在各个方面都得到了极大的改进:更强大的API、更高级的用户界面、改进的可用性、大量新区块、全站点编辑的首次实现等等.

简而言之,即使古腾堡仍在大力开发中,它也已经走过了漫长的道路——如今,区块编辑器已成为可靠的功能性页面和网站构建器的成熟候选者。

从开发人员的角度来看,Gutenberg是一个基于React的单页应用程序(SPA),它允许WordPress用户在WordPress中创建、编辑和删除内容。但是,这不应该让您想到传统内容编辑器的增强版。

我们想明确这一点:

Gutenberg不是常规的WYSIWYG编辑器。相反,它重新定义了WordPress中的整个编辑体验。

在古腾堡,内容被划分为区块,这些区块是用户可以用来创建文章和页面或整个网站的“砖块”。

但从技术上讲,什么是区块?

我们喜欢WordPress的定义

“区块”是用于描述标记单元的抽象术语,这些标记单元组合在一起形成网页的内容或布局。这个想法将我们今天在WordPress中实现的概念与短代码、自定义HTML和嵌入发现结合到一个一致的API和用户体验中。

标题、段落、列、图像、画廊以及构成编辑器界面的所有元素,从侧边栏面板到区块工具栏控件,都是React组件。

那么,什么是React组件?W3Schools提供以下定义

组件是独立且可重用的代码。它们的用途与JavaScript函数相同,但独立工作并通过render()函数返回HTML。

在WordPress 5.8中使用Gutenberg区块

在WordPress 5.8中使用Gutenberg区块

虽然Gutenberg提供的编辑体验与经典的WordPress编辑器相比是全新的,但WordPress将您的内容片段存储在数据库中的方式根本没有改变。这是因为Gutenberg是一个在WordPress中运行的应用程序,但不会改变CMS的核心工作方式。

使用Gutenberg创建的文章(包括文章、页面和自定义文章类型)仍存储在wp_posts表中,与经典编辑器完全相同。

但是在使用Gutenberg创建的文章中,您会在表格中找到更多信息,这些信息代表了通过Classic Editor与Gutenberg创建的文章之间的根本区别。

这些信息看起来像HTML注释,它们有一个特定的功能:分隔区块:

代码编辑器视图中的博客文章

代码编辑器视图中的博客文章。

区块分隔符告诉WordPress要在屏幕上呈现什么区块。它们还为JSON对象中的区块属性提供值。这些道具决定了区块应该在屏幕上呈现的方式:

wp_posts存储在表中的博客文章

wp_posts存储在表中的博客文章

设置您的WordPress开发环境

设置现代JavaScript开发环境需要扎实的高级技术知识,例如WebpackReactJSXBabelESLint等。

被吓倒了?不要!WordPress社区已经通过提供强大的工具来帮助您避免混乱的手动配置过程。

为简单起见,我们不会在本文中介绍转译(不过,我们建议您在了解区块开发的基础知识后熟悉一下)。相反,我们将介绍两种替代工具,您可以使用它们在几分钟内快速轻松地设置现代JavaScript开发环境。您可以选择对您的项目最方便的一个。

设置JavaScript开发环境以构建Gutenberg区块是一个三步过程:

  1. 安装Node.js和npm
  2. 设置开发环境
  3. 设置区块插件

让我们开始吧。

1. 安装Node.js和npm

在安装您的开发环境并注册您的第一个区块之前,您需要安装Node.js和Node包管理器 (npm)。

注:Node.js是基于Chrome的V8 JavaScript引擎构建的JavaScript运行时。npm,通常被称为Node包管理器,被认为是“世界上最大的软件注册表”。

您可以通过几种不同的方式安装Node.js和npm。但首先,您可能需要检查该软件是否已安装在您的计算机上。

为此,请启动终端并运行以下命令:

node -v

如果结果为command not found,则您的计算机上未安装Node.js,您可以继续安装。

对于本文,我们选择了最简单的安装选项,即Node Installer。您需要做的就是下载与您的操作系统相对应的版本并启动安装向导:

Node.js下载页面

Node.js下载页面

安装Node.js后,再次在终端中运行node -v命令。您还可以运行npm -v命令以确认您有可用的npm包。

您现在配备了以下工具:

  • npxNode.js包运行器(请参阅文档)。这允许您运行npm命令而无需先安装它。
  • npmNode.js包管理器(请参阅文档)。这用于安装依赖项和运行脚本。

下一步是安装开发环境。

2. 设置你的开发环境

在本地计算机上安装最新版本的Node.js和npm后,您将需要一个WordPress开发环境。

您可以使用本地开发环境,也可以使用官方WordPress工具。让我们来看看这两种选择。

选项 1:本地开发环境

您可以选择不同的本地开发工具,例如MAMPXAMPP

在本地环境中创建一个新的WordPress网站

在本地环境中创建一个新的WordPress网站。

选项 2:wp-env

您也可以选择官方wp-env工具,它提供了一个本地WordPress开发环境,您可以直接从命令行启动。Noah Alen将其定义如下

本地WordPress环境现在就像运行单个命令一样简单。wp-env是用于本地WordPress环境的零配置工具。它提供有关选项的决策,以便用户可以快速启动WordPress而不会浪费时间。事实上,我们的目标是让所有人都能轻松访问这些环境——无论您是开发人员、设计师、经理还是其他任何人。

如果您决定试一试,安装wp-env所需的工作量很小。只需按照以下步骤操作:

第 1 步:确认Docker和Node.js安装

为了满足技术要求,您首先需要在您的计算机上安装Docker和Node.js。那是因为wp-env创建了一个运行WordPress网站的Docker实例。对代码所做的任何更改都会立即反映在WordPress实例中。

第 2 步:从命令行安装@wordpress/env

在您的计算机上运行Docker和Node.js,您可以继续安装WordPress开发环境

您可以全局或本地安装wp-env。要在全局范围内执行此操作,您需要从插件目录中运行以下命令(更多信息请参见下面的“重要”通知框):

npm install -g @wordpress/env

让我们分解一下:

提示:默认情况下,在Mac或Linux上,节点包安装/usr/local/lib/node_modules中。

如果当前用户对该目录没有写权限,则会发出EACCES错误。了解有关在全局安装包时解决EACCES权限错误的更多信息。

要确认wp-env已成功安装,请运行以下命令:

wp-env --version

您应该会看到当前wp-env版本,这意味着您现在可以使用插件文件夹中的以下命令启动环境:

wp-env start

您可以使用以下地址访问WordPress仪表盘:

  • http://localhost:8888/wp-admin/

默认凭据如下:

  • 用户名:admin
  • 密码:password

设置你的区块插件

现在您需要一个入门区块插件来构建。但是,无需手动创建包含所有必要文件和文件夹的开发区块插件,您只需运行一个开发工具,即可提供开始区块开发所需的所有文件和配置。

同样,您有几个选项可供选择。让我们来看看每一个。

选项 1:使用@wordpress/create-block设置区块插件

@wordpress/create-block是用于创建Gutenberg区块的官方零配置工具:

创建区块是一种官方支持的创建区块的方法,用于为WordPress插件注册区块。它提供了一个没有配置的现代构建设置。它生成PHP、JS、CSS代码以及启动项目所需的所有其他内容。

它很大程度上受到create-react-app的启发。向@gaearon、整个Facebook团队和React社区致敬。

本地环境启动并运行后,您可以通过简单地运行命令npx @wordpress/create-block 来设置起始区块,它将提供创建插件脚手架和注册新区块所需的所有文件和文件夹。

让我们运行一个测试,看看它是如何工作的。

从命令行工具导航到/wp-content/plugins/目录并运行以下命令:

npx @wordpress/create-block my-first-block

当要求确认时,输入y继续:

使用@wordpress/create-block创建一个区块

使用@wordpress/create-block创建一个区块

该过程需要一些时间。完成后,您应该得到以下响应:

区块插件已创建

区块插件已创建

现在启动您的WordPress开发环境并转到WordPress仪表盘中的插件屏幕。一个名为“My First Block”的新插件应该已添加到您的插件列表中:

区块插件已成功安装

区块插件已成功安装

注:如果您使用wp-env工具并从包含插件的目录运行wp-env start,它将自动挂载并激活该插件。如果您从任何其他目录运行wp-env start,将创建一个通用的WordPress环境(另请参阅WordPress开发站点)。

如果需要,激活插件,创建一个新的博客文章,向下滚动区块插入器到小工具部分,然后选择你的新区块:

使用@wordpress/create-block创建的示例区块

使用@wordpress/create-block创建的示例区块

现在返回终端并将当前目录更改为my-first-block

cd my-first-block

然后运行以下命令:

npm start

这使您能够在开发模式下运行插件。要创建生产代码,您应该使用以下命令:

npm run build

选项 2:使用create-guten-block设置区块插件

create-guten-block是用于构建古腾堡区块的第三方开发工具:

create-guten-block零配置开发工具包 (#0CJS) 可在几分钟内开发WordPress Gutenberg区块,无需配置React、webpack、ES6/7/8/Next、ESLint、Babel等。

就像官方工具create-block一样,create-guten-block基于create-react-app,可以帮助您轻松生成您的第一个区块插件。

该工具包提供了创建现代WordPress插件所需的一切,包括以下内容

  • React、JSX和ES6语法支持。
  • 幕后的webpack开发/生产构建过程。
  • ES6之外的语言附加功能,例如对象扩展运算符。
  • 自动前缀CSS,因此您不需要 -webkit或其他前缀。
  • 一个构建脚本,用于将JS、CSS和图像与源映射捆绑在一起进行生产。
  • 使用单个依赖项cgb-scripts对上述工具进行无忧更新。

请注意以下警告:

权衡是这些工具已预先配置为以特定方式工作。如果您的项目需要更多自定义,您可以“eject” 并自定义它,但是您需要维护此配置。

一旦你手头有一个本地WordPress网站,启动你的命令行工具,导航到你安装的/wp-content/plugins文件夹,然后运行以下命令:

npx create-guten-block my-first-block

在创建项目结构并下载依赖项时,您必须等待一两分钟:

使用create-guten-block创建Gutenberg区块

使用create-guten-block创建Gutenberg区块

该过程完成后,您应该会看到以下屏幕:

使用create-guten-block成功创建Gutenberg区块

使用create-guten-block成功创建Gutenberg区块

下一张图片显示了在Visual Studio Code中运行终端的项目结构:

Visual Studio Code中的区块插件

Visual Studio Code中的区块插件

现在回到您的WordPress仪表盘。插件屏幕中应该会列出一个新项目——它是my-first-block插件:

使用create-guten-block创建的新插件的插件屏幕

使用create-guten-block创建的新插件的插件屏幕

激活插件并返回终端。将当前目录更改为my-first-block,然后运行npm start

cd my-first-block
npm start

您应该得到以下响应:

npm启动

npm启动

同样,这使您能够在开发模式下运行插件。要创建生产代码,您应该使用:

npm run build

激活插件并创建一个新文章或页面,然后浏览您的区块并选择您全新的古腾堡区块:

使用create-guten-block创建的新区块

使用create-guten-block创建的新区块

如需更深入的概述或出现错误,请参阅Ahmad Awais提供的文档

初学者区块脚手架的演练

无论您选择两种开发工具中的哪一种——create-block或者create-guten-block——您现在都有一个区块脚手架,您可以将其用作构建区块插件的起点。

但究竟什么是区块脚手架

区块脚手架是一个简写术语,描述了WordPress识别区块所需的支持目录结构。通常,该目录包括index.phpindex.jsstyle.css等文件,而这些文件又包含register_block_type.

我们选择了官方的Create Block开发工具,因为它在Block Editor Handbook中使用。但即使您决定使用第三方工具,例如create-guten-block,您的体验也不会有太大不同。

话虽如此,让我们更深入地了解该create-block工具

仔细查看Create Block开发工具

正如我们上面提到的,创建区块是创建古腾堡区块的官方命令行工具。在终端中运行@wordpress/create-block会生成注册新区块类型所需的PHP、JS和SCSS文件和代码:

npx @wordpress/create-block [options] [slug]
  • [slug](可选)- 用于分配区块slug并安装插件
  • [options](可选)- 可用选项

默认情况下,分配一个ESNext模板。这意味着您将获得JavaScript的下一个版本,并添加了JSX语法

如果您省略区块名称,该命令将以交互模式运行,使您能够在生成文件之前自定义多个选项:

npx @wordpress/create-block

在交互模式下运行create-block

在交互模式下运行create-block

下图显示了使用官方创建区块工具创建的区块插件的文件结构:

使用@wordpress/create-block创建的区块插件的文件和文件夹

使用@wordpress/create-block创建的区块插件的文件和文件夹

话虽如此,让我们浏览一下新区块插件的主要文件和文件夹。

插件文件

使用主插件文件在服务器上注册区块

/**
* Plugin Name: My First Block
* Description: Example block written with ESNext standard and JSX support – build step required.
* Requires at least: 5.8
* Requires PHP: 7.0
* Version: 0.1.0
* Author: The WordPress Contributors
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: my-first-block
*
* @package create-block
*/
/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/block-editor/tutorials/block-tutorial/writing-your-first-block-type/
*/
function create_block_my_first_block_block_init() {
register_block_type( __DIR__ );
}
add_action( 'init', 'create_block_my_first_block_block_init' );

register_block_type函数使用存储在block.json文件中的元数据在服务器上注册一个区块类型

该函数有两个参数:

  • 包含命名空间的区块类型名称,或者block.json文件所在文件夹的路径,或者一个完整的WP_Block_Type对象
  • 一组区块类型参数

在上面的代码中,区块类型参数由__DIR__ 魔术常量提供。这意味着block.json文件与插件文件位于同一文件夹中。

package.json文件

package.json文件为您的项目定义JavaScript属性和脚本。这是您可以安装项目依赖项的地方。

为了更好地理解此文件的用途,请使用您喜欢的代码编辑器打开它:

{
"name": "my-first-block",
"version": "0.1.0",
"description": "Example block written with ESNext standard and JSX support – build step required.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"main": "build/index.js",
"scripts": {
"build": "wp-scripts build",
"format": "wp-scripts format",
"lint:css": "wp-scripts lint-style",
"lint:js": "wp-scripts lint-js",
"start": "wp-scripts start",
"packages-update": "wp-scripts packages-update"
},
"dependencies": {
"@wordpress/block-editor": "^7.0.1",
"@wordpress/blocks": "^11.0.1",
"@wordpress/i18n": "^4.2.1"
},
"devDependencies": {
"@wordpress/scripts": "^18.0.0"
}
}

scripts 属性是一个字典其中包含使用npm run [cmd].

在本文中,我们将使用以下命令

  • npm run build— 创建一个(压缩的)生产版本
  • npm run start— 创建一个(未压缩的)开发版本

dependenciesdevDependencies将包名称映射到版本的两个对象。dependencies在生产中需要,而devDependences仅在本地开发中需要(阅读更多)。

唯一的默认开发依赖项是@wordpress/scripts包,它被定义为“为WordPress开发量身定制的可重用脚本的集合”。

block.json文件

从WordPress 5.8开始,block.json元数据文件是注册区块类型的规范方式。

拥有一个block.json文件有几个好处,包括提高性能和在WordPress插件目录上更好的可见性:

从性能的角度来看,当主题支持延迟加载资产时,使用block.json注册的区块将对其资产排队进行开箱即用的优化。stylescript属性中列出的前端CSS和JavaScript资产仅在页面上存在区块时才会入队,从而减少页面大小。

运行@wordpress/create-block命令会生成以下block.json文件:

{
"apiVersion": 2,
"name": "create-block/my-first-block",
"version": "0.1.0",
"title": "My First Block",
"category": "widgets",
"icon": "smiley",
"description": "Example block written with ESNext standard and JSX support – build step required.",
"supports": {
"html": false
},
"textdomain": "my-first-block",
"editorScript": "file:./build/index.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style-index.css"
}

这是默认属性的完整列表:

  • apiVersion— 区块使用的API版本(当前版本为2)
  • name— 包含命名空间的区块的唯一标识符
  • version— 区块的当前版本
  • title— 区块的显示标题
  • category— 区块类别
  • icon— Dashicon slug或自定义SVG图标
  • description— 在区块检查器中可见的简短描述
  • supports— 一组用于控制编辑器中使用的功能的选项
  • textdomain— 插件文本域
  • editorScript— 编辑器脚本定义
  • editorStyle— 编辑器样式定义
  • style— 为区块提供替代样式

除了上面列出的属性之外,您还可以(并且可能会)定义一个attributes对象,提供有关您的区块存储的数据的信息。在您的block.json中,您可以在键/值对中设置任意数量的属性,其中键是属性名称,值是属性定义。

看看下面的属性定义示例:

"attributes": {
"content": {
"type": "array",
"source": "children",
"selector": "p"
},
"align": {
"type": "string",
"default": "none"
},
"link": { 
"type": "string", 
"default": "https://www.zxtheme.com" 
}
},

我们将在本文后面深入研究block.json文件,但您可能还想查看区块编辑器手册以获取有关block.json元数据属性的更多详细信息。

src文件夹

src文件夹是开发发生的地方。在该文件夹中,您将找到以下文件:

  • index.js
  • edit.js
  • save.js
  • editor.scss
  • style.scss

index.js

index.js文件是您的起点。在这里,您将导入依赖项并在客户端上注册区块类型:

import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import save from './save';
registerBlockType('create-block/my-first-block', {
edit: Edit,
save,
});

第一条语句从@wordpress/blocks中导入函数registerBlockType。以下import语句将样式表与Editsave函数一起导入。

registerBlockType函数在客户端注册组件。该函数有两个参数:一个区块名称namespace/block-name(与在服务器上注册的相同)和一个区块配置对象。

Edit函数提供了在区块编辑器中呈现的区块界面,而save函数提供了将被序列化并保存到数据库中的结构(阅读更多)。

edit.js

edit.js是您构建区块管理界面的地方:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<p {...useBlockProps()}>
{__('My First Block – hello from the editor!', 'my-first-block')}
</p>
);
}

 

首先,它从@wordpress/i18n包中导入函数__(这个包包含翻译函数的JavaScript版本)、useBlockProps React钩子editor.scss文件。

之后,它会导出React组件(阅读有关导入导出语句的更多信息)。

save.js

save.js文件是我们构建要保存到数据库中的区块结构的位置

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
export default function save() {
return (
<p {...useBlockProps.save()}>
{__(
'My First Block – hello from the saved content!',
'my-first-block'
)}
</p>
);
}

editor.scss和style.scss

除了脚本之外,还有两个SASS文件位于src文件夹中。editor.scss文件包含应用于编辑器上下文中区块的样式,而style.scss文件包含用于在前端显示的区块的样式。我们将在本指南的第二部分深入研究这些文件。

node_modules和构建文件夹

node_modules文件夹包含节点模块及其依赖项。我们不会深入探讨节点包,因为它超出了本文的范围,但您可以在本文中阅读更多关于npm安装包的位置的文章

build文件夹包含构建过程产生的JS和CSS文件。您可以在ESNext语法JavaScript构建设置指南中深入了解构建过程。

项目:建造你的第一个古腾堡区块

是时候弄脏我们的手了。本节将教你如何创建一个插件,提供一个名为Affiliate Block的CTA区块。

该区块将由两列组成,左侧是图像,右侧是文本段落。带有可自定义链接的按钮将放置在文本下方:

您将在本指南中学习构建的区块类型

您将在本指南中学习构建的区块类型

这只是一个简单的示例,但它允许我们涵盖古腾堡区块开发的基础知识。一旦你清楚地了解了基础知识,你就可以在区块编辑器手册和任何其他可用的大量资源的帮助下继续创建越来越复杂的古腾堡区块。

Tips: 本教程中提供的示例代码也可以在Gist上找到,供您参考。

假设您在本地开发环境中运行了最新版本的WordPress,以下是您将从这里学到的内容:

如何设置初学者区块插件

启动命令行工具并导航到/wp-content/plugins文件夹:

Mac OS文件夹中的新终端

Mac OS文件夹中的新终端

现在,运行以下命令:

npx @wordpress/create-block

此命令生成用于在交互模式下注册区块的PHP、SCSS和JS文件,使您可以轻松地为您的区块添加必要的数据。对于我们的示例,我们将使用以下详细信息:

  • Block slug: my-affiliate-block
  • Internal namespace: my-affiliate-plugin
  • Block display title: Affiliate block
  • Short block description: An example block for Kinsta readers
  • Dashicon: money
  • Category name: design
  • Plugin author: your name
  • License: –
  • Link to the license text: –
  • Current plugin version: 0.1.0

安装插件和所有依赖项需要几分钟。该过程完成后,您将看到以下响应:

已安装并注册了Affiliate区块以进行开发

已安装并注册了Affiliate区块以进行开发

现在,从/wp-content/plugins文件夹运行以下命令:

cd my-affiliate-block

Tips: 如果您正在运行WordPress环境,则应首先启动Docker Desktop,然后从插件文件夹中运行wp-env start

然后,您可以从Web浏览器启动http://localhost:8888/wp-login并使用Username:adminPassword:password登录到您的WordPress仪表盘。

从Visual Studio代码终端运行命令

从Visual Studio代码终端运行命令

最后,在您的插件文件夹中(在我们的示例中为my-affiliate-block),您可以使用以下命令开始开发:

npm start

现在打开插件屏幕以查找并激活Affiliate Block插件:

Affiliate区块插件

Affiliate区块插件

创建一个新文章,打开区块插入器,然后向下滚动到设计Design类别。单击以添加Affiliate区块:

使用@wordpress/create-block构建的初学者区块

使用@wordpress/create-block构建的初学者区块

工作中的block.json

正如我们前面提到的,服务器端区块注册发生在主.php文件中。但是,我们不会在.php文件中定义设置。相反,我们将使用block.json文件。

因此,再次打开block.json并仔细查看默认设置:

{
"apiVersion": 2,
"name": "my-affiliate-plugin/my-affiliate-block",
"version": "0.1.0",
"title": "Affiliate Block",
"category": "design",
"icon": "money",
"description": "An example block for Kinsta readers",
"supports": {
"html": false
},
"textdomain": "my-affiliate-block",
"editorScript": "file:./build/index.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style-index.css"
}

脚本和样式

editorScripteditorStylestyle属性提供前端和后端脚本和样式的相对路径。

您不必手动注册此处定义的脚本和样式,因为它们是由WordPress自动注册和排队的。为了证明这一点,启动浏览器检查器并打开Network选项卡:

检查Chrome DevTools中的资源

检查Chrome DevTools中的资源

从上图中可以看出,我们驻留在build文件夹中的index.js脚本已定期排入队列,而无需添加任何PHP代码

用户界面标签

titledescription属性提供了在编辑器中识别区块所需的标签:

区块侧栏中的块名称和描述

区块侧栏中的区块名称和描述

关键词

正如我们之前提到的,您可以使用propertiesattributes准确地配置您的区块设置。例如,您可以添加一个或多个keywords来帮助用户搜索区块:

{ "keywords": [ "wbolt", "affiliate", "money" ] }

如果您现在在快速插入器中输入“wbolt”、“affiliate”或“money”,编辑器会建议您使用Affiliate区块:

在快速插入器中使用关键字搜索区块

在快速插入器中使用关键字搜索区块

本土化

如果您想知道JSON文件中字符串的本地化是如何发生的,答案如下:

在JavaScript中,您可以使用@wordpress/blocks包中的now registerBlockTypeFromMetadata方法使用从block.json文件加载的元数据注册区块类型。所有本地化属性都会自动包装在_x(来自 @wordpress/i18n包)函数调用中,类似于它在PHP中的register_block_type_from_metadata工作方式。唯一的要求是在block.json文件中设置textdomain属性。

这里我们使用registerBlockType函数而不是registerBlockTypeFromMetadata,因为后者自古腾堡10.7以来已被弃用,但机制是相同的。

使用内置组件:RichText组件

构成Gutenberg区块的元素是React组件,您可以通过wp全局变量访问这些组件。例如,尝试在浏览器的控制台中输入wp.editor。这将为您提供wp.editor模块中包含的组件的完整列表。

滚动列表并猜测其名称所代表的组件。

同样,您可以检查wp.components模块中包含的组件列表:

WP编辑器组件

WP编辑器组件

Tips: 模块化编程是一种软件设计技术,强调将程序的功能分离为独立的、可互换的模块,这样每个模块都包含执行所需功能的一个方面所需的一切(来源:维基百科)。

现在回到edit.js文件并仔细查看脚本:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<p {...useBlockProps()}>
{__('My First Block – hello from the editor!', 'my-first-block')}
</p>
);
}

此代码生成一个带有简单、不可编辑文本的静态区块。但是我们可以很容易地改变:

代码编辑器中的初学者区块

代码编辑器中的初学者区块

要使文本可编辑,您必须将当前<p>标记替换为使输入内容可编辑的组件。为此,Gutenberg提供了内置的RichText组件

将内置组件添加到区块中需要5个步骤:

  1. 从WordPress包中导入所需的组件
  2. 在JSX代码中包含相应的元素
  3. 在block.json文件中定义必要的属性
  4. 定义事件处理程序
  5. 保存数据

第 1 步:从WordPress包中导入所需的组件

现在打开edit.js文件并更改以下import语句:

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

…到:

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

这样,您就可以从 @wordpress/block-editor包中导入useBlockProps函数和 RichText组件。

使用BlockProps

useBlockPropsReact钩子标记了区块的wrapper元素

使用API版本2时,您必须使用区块函数edit中的新钩子useBlockProps来标记区块的wrapper元素。该钩子将插入启用区块行为所需的属性和事件处理程序。您希望传递给区块元素的任何属性都必须通过useBlockProps传递,并且返回的值必须分布到元素上。

简单地说,useBlockProps自动将属性和类分配给wrapper元素(我们示例中的p元素):

由useBlockProps生成的元素和类

由useBlockProps生成的元素和类

如果useBlockProps从wrapper元素中删除,您将拥有一个简单的文本字符串,无法访问区块功能和样式:

没有useBlockProps的同一个区块

没有useBlockProps的同一个区块

正如我们稍后将解释的,您还可以传递给useBlockProps属性对象来自定义输出。

富文本

RichText组件提供了一个contenteditable输入,允许用户编辑和格式化内容。

您可以在GitHub上的gutenberg/packages/block-editor/src/components/rich-text/README.md找到该组件。

第 2 步:在JSX代码中包含相应的元素

...
const blockProps = useBlockProps();
return (
<RichText 
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
/>
);

让我们逐行注释代码:

  • tagName— 可编辑HTML元素的标签名称
  • onChange— 当元素内容改变时调用的函数
  • allowedFormats— 一组允许的格式。默认情况下,允许所有格式
  • value— 可编辑的HTML字符串
  • placeholder— 当元素为空时显示的占位符文本

第 3 步:在block.json文件中定义必要的属性

属性提供有关区块存储的数据的信息,例如丰富的内容、背景颜色、URL等。

您可以在一个对象中以键/值对的形式设置任意数量的属性attributes,其中键是属性名称,值是属性定义。

现在打开block.json文件并添加以下属性attributes

"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
}
},

content属性允许将用户输入的文本存储在可编辑字段中:

  • type表示属性存储的数据类型。除非您定义enum属性,否则该类型是必需的。
  • source定义如何从文章内容中提取属性值。在我们的示例中,它是HTML内容。请注意,如果您不提供源属性,则数据将存储在区块分隔符中(阅读更多)。
  • selector是HTML标记或任何其他选择器,例如类名或id属性。

我们将向Edit函数传递一个属性对象。因此,返回到edit.js文件并进行以下更改:

export default function Edit( { attributes, setAttributes } ) { ... }

第 4 步:定义事件处理程序

RichText元素有一个onChange属性,当元素的内容改变时提供一个函数来调用。

让我们定义该函数并查看整个edit.js脚本:

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } )
}
return (
<RichText 
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
/>
);
}

现在保存文件并在终端窗口中运行npm run start。然后,返回您的WordPress仪表盘,创建一个新文章或页面并添加您的Affiliate区块:

区块编辑器中RichText组件的输出

区块编辑器中RichText组件的输出

添加一些文本并切换到代码视图。这是您的代码应如下所示:

<!-- wp:my-affiliate-plugin/my-affiliate-block -->
<p class="wp-block-my-affiliate-plugin-my-affiliate-block">This is my first editable Gutenberg block 🤓</p>
<!-- /wp:my-affiliate-plugin/my-affiliate-block -->

如果您现在保存页面并检查前端结果,您可能会有点失望,因为您的更改不会影响站点。那是因为您必须修改save.js文件以在保存文章时将用户输入存储在数据库中。

第 5 步:保存数据

现在打开save.js文件并更改脚本如下:

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
return (
<RichText.Content 
{ ...blockProps } 
tagName="p" 
value={ attributes.content } 
/>
);
}

这就是我们在这里所做的:

  • RichText从包中导入组件block-editor
  • 通过一个对象参数向save函数传递几个属性(在这个例子中,我们只传递了attributes属性
  • 返回组件的RichText内容

注:每当您更改保存功能时,您必须删除编辑器画布中的任何区块实例并再次包含它以查看它是否正常工作。阅读有关区块验证的更多信息。

您可以在区块编辑器手册中阅读有关该RichText组件的更多信息,并在Github上找到完整的道具列表。

现在让我们更进一步。在下一节中,您将学习如何将控件添加到区块工具栏。

向区块工具栏添加控件

区块工具栏包含一组控件,允许用户操作部分区块内容。对于每个工具栏控件,您都会找到一个组件:

核心段落区块工具栏

核心段落区块工具栏

例如,您可以为区块添加文本对齐控件。您需要做的就是从@wordpress/block-editor包中导入两个组件。

我们将执行与上一个示例相同的步骤:

  1. 从WordPress包中导入所需的组件
  2. 在JSX代码中包含相应的元素
  3. block.json文件中定义必要的属性
  4. 定义事件处理程序
  5. 保存数据

第 1 步:从@wordpress/block-editor导入BlockControls和AlignmentControl组件

要将对齐控件添加到区块工具栏,您需要两个组件:

  • BlockControls呈现控件的动态工具栏(未记录)。
  • AlignmentControl呈现一个下拉菜单,显示所选区块的对齐选项(阅读更多

打开edit.js文件,编辑import语句如下图:

import { 
useBlockProps, 
RichText, 
AlignmentControl, 
BlockControls 
} from '@wordpress/block-editor';

第 2 步:添加BlockControls和AlignmentControl元素

转到Edit函数并插入与<RichText />相同级别的元素<BlockControls />。然后在<BlockControls />内添加和<AlignmentControl />

export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
return (
<>
<BlockControls>
<AlignmentControl
value={ attributes.align }
onChange={ onChangeAlign }
/>
</BlockControls>
<RichText 
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
style={ { textAlign: attributes.align } }
/>
</>
);
}

在上面的代码中,<></>是声明React片段的简短语法,这是我们在React中返回多个元素的方式。

在这个例子中,AlignmentControl有两个属性:

我们还为RichText元素定义了额外的属性(查看完整的属性列表和示例

第三步:在block.json中定义align属性

现在转到block.json文件并添加align属性:

"align": {
"type": "string",
"default": "none"
}

返回终端,使用^C停止当前进程并使用npm run start重新启动脚本。然后返回区块编辑器,刷新页面并选择区块。您应该会看到带有对齐控件的区块工具栏:

对齐工具栏已成功添加

对齐工具栏已成功添加

现在,如果您尝试使用新的对齐控件格式化区块内容,您会发现没有任何反应。那是因为我们还没有定义事件处理程序。

第 4 步:定义事件处理程序

现在定义onChangeAlign

const onChangeAlign = ( newAlign ) => {
setAttributes( { 
align: newAlign === undefined ? 'none' : newAlign, 
} )
}

如果newAlignundefined,那么我们设置newAlignnone。否则,我们使用newAlign.

我们的edit.js脚本应该是完整的(现在):

export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } )
}
const onChangeAlign = ( newAlign ) => {
setAttributes( { 
align: newAlign === undefined ? 'none' : newAlign, 
} )
}
return (
<>
<BlockControls>
<AlignmentControl
value={ attributes.align }
onChange={ onChangeAlign }
/>
</BlockControls>
<RichText 
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
style={ { textAlign: attributes.align } }
/>
</>
);
}

现在您可以返回编辑器并对齐区块内容。

我们需要修改save函数,将区块的内容和属性存储在数据库中。

第 5 步:保存数据

打开save.js,修改save函数如下:

export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
return (
<RichText.Content 
{ ...blockProps } 
tagName="p" 
value={ attributes.content } 
style={ { textAlign: attributes.align } }
/>
);
}

最后,为了使代码更具可读性,您可以使用解构赋值语法attribute对象中提取各个属性:

export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
const { content, align } = attributes;
return (
<RichText.Content 
{ ...blockProps } 
tagName="p" 
value={ content } 
style={ { textAlign: align } }
/>
);
}

保存文件,重新启动进程并以代码编辑器模式返回编辑器。代码应如下所示:

<!-- wp:my-affiliate-plugin/my-affiliate-block {"align":"right"} -->
<p class="wp-block-my-affiliate-plugin-my-affiliate-block" style="text-align:right">This is my first editable <strong><em>Gutenberg</em></strong> <em>block</em> 🤓</p>
<!-- /wp:my-affiliate-plugin/my-affiliate-block -->

右对齐文本

右对齐文本

就是这样!您刚刚向区块工具栏添加了对齐控件🤓

您可以在区块编辑器手册中阅读有关区块工具栏控件的更多信息

自定义区块设置侧边栏

您还可以将控件添加到区块设置侧边栏(甚至为您的应用程序创建一个新的侧边栏)。

API为此提供了一个InspectorControls组件

区块编辑器手册解释了如何使用设置边栏

设置侧边栏用于显示不常用的设置或需要更多屏幕空间的设置。设置侧边栏应仅用于块级设置

如果您的设置仅影响区块内的选定内容(例如:段落内选定文本的“粗体”设置):请勿将其放在设置侧边栏中。即使在HTML模式下编辑区块时也会显示设置侧边栏,因此它应该只包含区块级设置。

再次:

  1. 从WordPress包中导入所需的组件
  2. 在JSX代码中包含相应的元素
  3. 在block.json文件中定义必要的属性
  4. 定义事件处理程序
  5. 保存数据

步骤 1. 从@wordpress/block-editor导入InspectorControls和PanelColorSettings组件

您可以添加多个控件以允许用户自定义区块的特定方面。例如,您可以提供一个颜色控制面板。为此,您需要从block-editor模块中导入InspectorControlsPanelColorSettings组件:

import { 
useBlockProps, 
RichText, 
AlignmentControl, 
BlockControls,
InspectorControls,
PanelColorSettings
} from '@wordpress/block-editor';

第 2 步:在JSX代码中包含相应的元素
现在您可以将相应的元素添加到Edit函数返回的JSX中:

export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } )
}
const onChangeAlign = ( newAlign ) => {
setAttributes( { 
align: newAlign === undefined ? 'none' : newAlign, 
} )
}
return (
<>
<InspectorControls>
<PanelColorSettings 
title={ __( 'Color settings', 'my-affiliate-block' ) }
initialOpen={ false }
colorSettings={ [
{
value: textColor,
onChange: onChangeTextColor,
label: __( 'Text color', 'my-affiliate-block' ),
},
{
value: backgroundColor,
onChange: onChangeBackgroundColor,
label: __( 'Background color', 'my-affiliate-block' ),
}
] }
/>
</InspectorControls>
<BlockControls>
<AlignmentControl
value={ attributes.align }
onChange={ onChangeAlign }
/>
</BlockControls>
<RichText 
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...', 'my-affiliate-block' ) }
style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>
</>
);
}

请注意,我们还更新了RichText元素的style属性:

<RichText 
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ content }
placeholder={ __( 'Write your text...', 'my-affiliate-block' ) }
style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>

第 3 步:在block.json中定义必要的属性

现在在block.json文件中定义backgroundColortextColor属性:

"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
},
"align": {
"type": "string",
"default": "none"
},
"backgroundColor": {
"type": "string"
},	 
"textColor": {
"type": "string"
}
},

第 4 步:定义事件处理程序

现在您需要定义backgroundColortextColor两个函数来更新用户输入:

const onChangeBackgroundColor = ( newBackgroundColor ) => {
setAttributes( { backgroundColor: newBackgroundColor } )
}
const onChangeTextColor = ( newTextColor ) => {
setAttributes( { textColor: newTextColor } )
}

第 5 步:保存数据

最后一步:打开save.js文件并按如下方式更改脚本:

export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
const { content, align, backgroundColor, textColor } = attributes;
return (
<RichText.Content 
{ ...blockProps } 
tagName="p" 
value={ content } 
style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>
);
}

现在停止进程 (^C) 并再次运行npm run start。刷新页面,删除任何区块实例并将其再次添加到您的文章中:

带有颜色设置面板的自定义区块

带有颜色设置面板的自定义区块

进行更改,保存文章,然后在前端查看。您在区块编辑器中所做的更改应反映在前端站点上。

在本节中,您将向区块类型添加新组件:

  • ExternalLink允许用户将可自定义链接添加到Affiliate区块的组件
  • 几个侧边栏控件允许用户自定义链接设置

步骤 1. 从@wordpress/components导入组件

现在需要从@wordpress/components导入几个组件。打开你的edit.js文件并添加以下import语句:

import {
TextControl,
PanelBody,
PanelRow,
ToggleControl,
ExternalLink
} from '@wordpress/components';
  • PanelBody将可折叠容器添加到设置侧边栏。
  • PaneRow为侧边栏控件生成一个通用容器。
  • TextControl提供文本输入控件。
  • ToggleControl提供一个切换,使用户能够启用/禁用特定选项
  • ExternalLink是一个添加外部链接的简单组件。

步骤 2. 在JSX代码中包含相应的元素

您将首先在div容器中添加ExternalLinkRichText相同级别的元素:

<div { ...blockProps }>
<RichText 
...
/>
<ExternalLink 
href={ affiliateLink }
className="affiliate-button"
rel={ hasLinkNofollow ? "nofollow" : "" }
>
{ linkLabel }
</ExternalLink>
</div>

ExternalLink组件没有记录,因此我们参考了组件本身来获取可用属性的列表。这里我们使用hrefclassNamerel属性。

默认情况下,rel属性值设置为noopener noreferrer。当切换控件为on时,我们的代码将把nofollow添加到生成的标记的rel属性中。

现在您可以将链接设置添加到区块侧边栏。

首先,在InspectorControls中添加一个与PanelColorSettings处于同一级别的PanelBody元素:

<InspectorControls>
<PanelColorSettings 
...
/>
<PanelBody 
title={ __( 'Link Settings', 'my-affiliate-block' )}
initialOpen={true}
>
...
</PanelBody>
</InspectorControls>

这是我们正在做的事情:

  1. title属性提供面板标题。
  2. initialOpen设置面板最初是否打开。

接下来,我们将在PanelBody内部添加两个元素PanelRow,并在每个PanelRow内部添加一个TextControl元素:

<PanelBody 
title={ __( 'Link Settings', 'my-affiliate-block' )}
initialOpen={true}
>
<PanelRow>
<fieldset>
<TextControl
label={__( 'Affiliate link', 'my-affiliate-block' )}
value={ affiliateLink }
onChange={ onChangeAffiliateLink }
help={ __( 'Add your affiliate link', 'my-affiliate-block' )}
/>
</fieldset>
</PanelRow>
<PanelRow>
<fieldset>
<TextControl
label={__( 'Link label', 'my-affiliate-block' )}
value={ linkLabel }
onChange={ onChangeLinkLabel }
help={ __( 'Add link label', 'my-affiliate-block' )}
/>
</fieldset>
</PanelRow>
</PanelBody>

上面的代码现在看起来应该很简单了。这两个文本控件允许用户设置链接标签和URL。

我们还将添加一个附加选项来打开/关闭特定选项,例如是否包含属性:

我们还将添加一个带有ToggleControl的额外PanelRow,以打开/关闭特定选项,例如是否包含属性:

<PanelRow>
<fieldset>
<ToggleControl
label="Add rel = nofollow"
help={
hasLinkNofollow
? 'Has rel nofollow.'
: 'No rel nofollow.'
}
checked={ hasLinkNofollow }
onChange={ toggleNofollow }
/>
</fieldset>
</PanelRow>

第 3 步:在block.json中定义必要的属性

现在在block.json文件中定义affiliateLinklinkLabelhasLinkNofollow属性:

"affiliateLink": {
"type": "string",
"default": ""
},
"linkLabel": {
"type": "string",
"default": "Check it out!"
},
"hasLinkNofollow": {
"type": "boolean",
"default": false
}

这里没有什么要补充的了!让我们继续定义事件处理函数

第 4 步:定义事件处理程序

回到edit.js文件并添加以下函数:

const onChangeAffiliateLink = ( newAffiliateLink ) => {
setAttributes( { affiliateLink: newAffiliateLink === undefined ? '' : newAffiliateLink } )
}
const onChangeLinkLabel = ( newLinkLabel ) => {
setAttributes( { linkLabel: newLinkLabel === undefined ? '' : newLinkLabel } )
}
const toggleNofollow = () => {
setAttributes( { hasLinkNofollow: ! hasLinkNofollow } )
}

这些函数更新用户输入的相应属性值。

第 5 步:保存数据

最后,我们必须更新save.js中的save函数:

export default function save( { attributes } ) {
const { align, content, backgroundColor, textColor, affiliateLink, linkLabel, hasLinkNofollow } = attributes;
const blockProps = useBlockProps.save();
return (
<div { ...blockProps }>
<RichText.Content 
tagName="p" 
value={ content } 
style={ { backgroundColor: backgroundColor, color: textColor } }
/>
<p>
<a 
href={ affiliateLink }
className="affiliate-button"
rel={ hasLinkNofollow ? "nofollow" : "noopener noreferrer" }
>
{ linkLabel }
</a>
</p>
</div>
);
}

请注意,这里我们使用了常规a元素而不是ExternalLink

Affiliate区块链接设置

Affiliate区块链接设置

现在保存数据并重新启动您的环境。

添加多个区块样式

在上一节中,您学习了如何添加允许用户对齐用户输入的区块工具栏控件。我们可以向区块工具栏添加更多样式控件,但我们也可以提供一组预定义的区块样式,用户只需单击即可从中选择。

为此,我们将使用Block API的一个有用功能:Block Styles

您需要做的就是定义block.json styles属性并在样式表中声明相应的样式。

例如,您可以添加以下样式数组:

"styles": [
{
"name": "default",
"label": "Default",
"isDefault": true
},
{
"name": "border",
"label": "Border"
}
],

有了这个,您刚刚添加了一个默认样式和一个名为border. 现在回到区块编辑器:

两种预定义的区块样式

两种预定义的区块样式

通过单击区块切换器,然后在区块设置侧边栏中查找样式面板,用户可以使用样式。

选择一种样式并检查应用于p元素的类。右键单击区块并检查。添加了一个新类,其名称结构如下:

is-style-{style-name}

如果您选中了“Border”样式,则会将一个is-style-border类添加到p元素中。如果您选中“Default”样式,则会添加一个is-style-default类。

现在您只需要声明CSS属性。打开editor.scss文件并将当前样式替换为以下内容:

.wp-block-my-affiliate-plugin-my-affiliate-block {
padding: 2px;
&.is-style-default{
border: 0;
}
&.is-style-border{
border: 1px solid #000;
}
}

现在你可以对style.scss做同样的事情:

.wp-block-my-affiliate-plugin-my-affiliate-block {
&.is-style-default{
border: 0;
}
&.is-style-border{
border: 1px solid #000;
}
}

停止进程 (^C) 并再次运行npm run start

就是这样!刷新页面,享受新的区块样式:

Affiliate区块样式

Affiliate区块样式

使用InnerBlocks组件嵌套Gutenberg区块

虽然功能齐全,但我们的Affiliate区块仍然不是很吸引人。为了让观众更感兴趣,我们可以添加一张图片。

这可能会给我们的区块增加一层复杂性,但幸运的是,您不需要重新发明轮子,因为Gutenberg提供了一个特定的组件,您可以使用它来创建嵌套区块的结构。

InnerBlocks组件定义如下

InnerBlocks导出一对可用于区块实现以启用嵌套区块内容的组件。

首先,您需要在src文件夹中创建一个新的.js文件。在我们的示例中,我们将此文件称为container.js

现在您需要将新资源导入index.js文件:

import './container';

回到container.js并导入必要的组件:

import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import {
useBlockProps, 
InnerBlocks 
} from "@wordpress/block-editor";

下一步是定义一个模板,提供将放置区块的结构。在以下示例中,我们定义了一个模板,该模板由两列组成,其中包含一个核心Image区块和我们的自定义Affiliate区块:

const TEMPLATE = [ [ 'core/columns', { backgroundColor: 'yellow', verticalAlignment: 'center' }, [
[ 'core/column', { templateLock: 'all' }, [
[ 'core/image' ],
] ],
[ 'core/column', { templateLock: 'all' }, [
[ 'my-affiliate-plugin/my-affiliate-block', { placeholder: 'Enter side content...' } ],
] ],
] ] ];

模板的结构是一个blockTypes 数组(区块名称和可选属性)。

在上面的代码中,我们使用了几个属性来配置Columns和Column区块。具体来说,templateLock: 'all'属性锁定Column区块,以便用户不会添加、重新排序或删除现有区块。templateLock可以采用以下值之一:

  • allInnerBlocks已锁定,不能添加、重新排序或删除任何区块。
  • insert— 区块只能重新排序或删除。
  • false— 模板未锁定。

然后将模板分配给InnerBlocks元素:

<InnerBlocks
template={ TEMPLATE }
templateLock="all"
/>

为了防止出现任何兼容性问题,我们还为InnerBlocks组件添加了一个templateLock属性(另请参阅issue #17262和pull #26128)。

这是我们最终的container.js文件:

import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import { useBlockProps, InnerBlocks } from "@wordpress/block-editor";
const TEMPLATE = [ [ 'core/columns', { backgroundColor: 'yellow', verticalAlignment: 'center' }, [
[ 'core/column', { templateLock: 'all' }, [
[ 'core/image' ],
] ],
[ 'core/column', { templateLock: 'all' }, [
[ 'my-affiliate-plugin/my-affiliate-block', { placeholder: 'Enter side content...' } ],
] ],
] ] ];
registerBlockType('my-affiliate-plugin/my-affiliate-container-block', {
title: __( 'Container', 'my-affiliate-block' ),
category: 'design',
edit( { className } ) {
return(
<div className={ className }>
<InnerBlocks
template={ TEMPLATE }
templateLock="all"
/>
</div>
)
},
save() {
const blockProps = useBlockProps.save();
return(
<div { ...blockProps }>
<InnerBlocks.Content />
</div>
)
},
});

编辑器中的嵌套Affiliate区块

编辑器中的嵌套Affiliate区块

其他改进

我们的区块功能齐全,但我们可以通过一些小改动对其进行一些改进。

我们将backgroundColor属性分配给RichText组件生成的段落。但是,我们可能更喜欢将背景颜色分配给容器div

所以,修改edit.js文件和save.js的 div如下:

<div 
{ ...blockProps }
style={ { backgroundColor: backgroundColor } }
>
...
</div>

这将允许用户更改整个区块的背景。

另一方面,更相关的变化涉及useBlockProps方法。在原始代码中,我们定义常量blockProps如下:

const blockProps = useBlockProps();

但是我们可以使用useBlockProps更有效的传递一组属性。例如,我们可以从classnames模块导入classnames并相应地设置wrapper类名称。

在以下示例中,我们根据align属性的值分配一个类名 ( edit.js ):

import classnames from 'classnames';
...
export default function Edit( { attributes, setAttributes } ) {
...
const blockProps = useBlockProps( {
className: classnames( {
[ `has-text-align-${ align }` ]: align,
} )
} );
...
}

我们将在save.js文件中进行相同的更改:

import classnames from 'classnames';
...
export default function save( { attributes } ) {
...
const blockProps = useBlockProps.save({
className: classnames( {
[ `has-text-align-${ align }` ]: align,
} )
});
...
}

这是一个wrap!您现在可以为生产运行构建

小结

我们到了,在这个令人难以置信的旅程的尽头!我们从开发环境的配置开始,最终创建了一个完整的区块类型。

正如我们在介绍中提到的,Node.js、Webpack、Babel和React的扎实知识对于创建高级Gutenberg区块并将自己定位为专业的Gutenberg开发人员至关重要。

但是,您无需具备React经验即可开始享受区块开发的乐趣。区块开发可以为您提供动力和目标,让您在古腾堡区块背后的技术中获得越来越广泛的技能。

因此,本指南远未完成。它只是对各种主题的介绍,可帮助您开始构建您的第一个古腾堡区块。

因此,我们建议您通过仔细阅读在线文档和指南来加深您的知识。在可用的众多资源中,我们推荐以下内容:

如果您刚开始WordPress开发,您可能想了解前端开发的基本概念。以下是可以帮助您入门的资源的快速列表:

请记住,本指南示例的完整代码可在Gist上找到