学习 Gutenberg:使用 create-guten-block 的入门指南

Avatar of Lara Schenck
Lara Schenck 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

欢迎回来!我们刚刚了解了 Gutenberg 是什么以及它在管理员侧是如何运作的。Gutenberg 肯定会对 WordPress 世界产生巨大影响。如果您是第一次来到这里,并且不知道我们在说什么,我建议您至少浏览一下第一部分,以确保您具备必要的背景知识。

让我们借助一个名为 create-guten-block 的出色工具,创建一个自定义块。出发吧!

文章系列

  1. 系列介绍
  2. Gutenberg 到底是什么?
  3. 使用 create-guten-block 的入门指南 (本篇)
  4. 现代 JavaScript 语法
  5. React 101
  6. 设置自定义 Webpack
  7. 自定义“卡片”块

块存在于插件中

要创建 Gutenberg 块,您需要创建一个 WordPress 插件。任何影响内容的东西,比如 Gutenberg 块,都必须是插件,以便即使在您更改主题时也能保持活动状态。主题特定的内容或仅影响网站外观的内容可以是主题文件的一部分或主题中的functions.php文件。在我们的关于WordPress 功能插件的文章中阅读更多关于此区别的信息。

也就是说,主题中的块问题是一个热门话题。WordPress 主题审查团队正在讨论是否允许在主题中使用块。在主题审查团队的 Make 页面上的一篇帖子“为 Gutenberg 做准备”提出了这个问题,并引起了双方强烈的意见。然而,普遍共识是,块属于插件的领域。

WordPress.org 由多个团队组成,每个团队在make.wordpress.org/team-name都有自己的主页,在 WordPress Slack 中有自己的频道,以及每周的会议。如果您有兴趣参与 WordPress 或了解它的运作方式,我强烈建议您浏览此处列出的团队,加入 Slack 频道,并参加每周的会议,了解所有事情是如何发生的。

在遥远的将来,主题可能仅由样式表组成,而所有自定义功能和内容结构都来自插件中的块。我正在转述 Gutenberg 的设计主管Tammie ListerShoptalk Show 的这一期节目中的话。非常值得一听!

暂时采取设置捷径

阻止我一头扎进现代 JavaScript 的是讨厌的配置。转译、打包、代码分割、树摇……哎呀,我太忙了!我喜欢学习新事物,但我的耐心是有限的,而且显然,为一个小测试项目配置构建过程是我的极限。

正是这种情绪导致了名为 create-react-app 的工具的开发,这是一个零配置构建设置,用于(您猜对了)创建 React 应用程序。它很棒。假设您已安装了正常运行的nodenpm,您可以运行单个命令,然后您就拥有了一个可以开始使用 React 编码的项目。转译、打包和树摇都已为您设置好。

但是等等……我们能否将create-react-app用于 Gutenberg 块?不能,但前面提到的 create-guten-block(由 Ahmad Awais 开发并记录得非常好)为我们做了几乎同样的事情!这就是我们将用于块的工具。

create-guten-block并不是我们唯一可用的块生成工具!您可以使用 脚手架块WP-CLI,但我选择不使用它,因为默认设置是针对 ES5 的(目前),并且没有提供我们进入现代 JavaScript 所需的功能。话虽如此,我发现深入研究块的 ES5 实现有助于强化核心概念,所以也许您可以在完成此操作后尝试一下!

是的,这是一个捷径。我们选择通过使用工具来避免理解一项技术的核心概念。我们总有一天必须学习这些概念。但就目前而言,我完全可以绕过此配置步骤。我关于使用此类工具的理念:使用它们,但要了解它可能不会从长远来看为您节省时间或精力。

值得注意的是,与create-react-app类似,create-guten-block允许您将配置npm eject出来。这意味着公开该工具为我们创建的所有设置,并使其可供自定义。但是请注意,这是不可逆的;如果您弹出并犯了错误,那么您需要自己修复它!就像我说的,您总有一天必须学习它 :)

步骤 1:安装 create-guten-block

我们首先全局安装create-guten-block,如下所示

npm install -g create-guten-block

理论上这应该没问题,但这不切实际。create-guten-block需要 Node 版本 8 和 npm 5.3 或更高版本,因此,如果您有一段时间没有更新过它们中的任何一个,那就是一个可能出现的错误(并且这里有一个可能的解决方案)。

我总是先将控制台错误粘贴到搜索引擎中,并删除行号和文件名以保持查询的通用性。但是,为了改进本教程,我很好奇了解出了什么问题,因此请随时在评论中发布您的问题。

步骤 2:创建该 Gutenberg 块

是时候了!让我们开始吧!您知道吗?我不会告诉您方法,因为 Ahmad 的文档写得非常好,并且没有必要重复它。

请访问此处,并按照 Ahmad 的说明在您的命令行中创建该 Gutenberg 块。

A screenshot of the integrated terminal showing the build process has started
运行命令 create-guten-block test 时,您应该会看到类似以下内容,其中“test”是我的块的名称。

步骤 3:激活插件

转到您的插件屏幕,激活您的新块插件——它应该被称为类似test-block — CGB Gutenberg 块插件的内容,其中“test-block”是您在创建块时为其指定的名称。

Screenshot of the Plugins screen of the WordPress admin showing the create-guten-block plugin is active

步骤 4:就是这样!让我们使用我们的自定义块!

太简单了!现在,转到帖子或页面的编辑器视图,找到您的块,然后插入它。

Animated GIF showing the selection and insertion of the default block from create-guten-block

尽管我将块命名为“test”,但在块选择器中搜索“test”却产生了错误的结果,如上面的 GIF 所示。块的默认名称改为“CGB 块”——我们很快就会更改它!

文本编辑器设置(可选)

我发现为开发区块设置一个特定的文本编辑器非常有用。我使用Visual Studio Code作为我的文本编辑器,但相信你可以根据自己的喜好,找到类似的编辑器。

以下是关键要素:

  1. 轻松访问命令行,以便随时关注构建错误(肯定会有构建错误)。
  2. 从 GitHub 获取 Gutenberg 源代码以供参考(在此处下载或克隆)。
  3. 轻松访问你的插件目录和来自 #2 的 Gutenberg 源代码目录。
A screenshot of the VS Code text editor, showing the integrated terminal and sidebar of folders
我用于 Gutenberg 开发的 VS Code 设置。请注意集成的终端和左侧的多个源代码目录。

在 VS Code 中,我使用以下功能实现这一点:

  1. 集成的终端——在 Mac 上使用 Command + ~ 打开,或从菜单栏中选择“查看 > 集成终端”。
  2. 一个包含插件文件夹和来自 GitHub 的 Gutenberg 源代码文件夹的工作区。你可以通过在 VS Code 中打开你的插件目录,然后选择“文件 > 将文件夹添加到工作区”并选择从 GitHub 存储库下载的 Gutenberg 目录来完成此操作。然后,你可以通过“文件 > 另存为工作区”保存工作区以便轻松访问(我在上图中将其命名为“区块”)。

这部分是可选的,你不需要使用 VS Code。重要的是能够轻松访问命令行、你的插件源代码以及 Gutenberg 插件源代码以供参考。如果你愿意,完全可以在 GitHub 上参考源代码,但我更喜欢将文件放在同一个环境中,以便进行并排比较和使用“在文件夹中查找”轻松搜索。

我们使用插件存储库中的 Gutenberg 来实现实际的功能,但该实例仅包含编译后的文件。我们希望参考源文件,因此我们需要直接使用来自 GitHub 的代码库。如果你想在插件发布之前访问更新,可以克隆存储库。完全有可能从 GitHub 版本构建和工作,但为了简单起见,本教程中我们使用插件版本。

Gutenberg 本身不再是一个插件,它已内置于 WordPress 5.0 及更高版本中。这篇文章介绍了在哪里获取/查看该代码。

准备就绪后,确保你已 cd 到你的区块插件文件夹并运行 npm start。你应该会看到一条令人满意的消息,指示该过程已开始。

A screenshot of the integrated terminal showing the build process has started
在我们的插件文件夹中运行 npm start 后,我们正式开始“监视更改……”(而且我们不必触碰任何配置!作弊者……)。

我使用Wes BosVS Code 中的 Cobalt 2 主题,以及终端和 iTerm 中的相同 ZSH 主题。这完全不会影响技术的工作方式,但确实会在个人层面上有所不同,可以自定义你的工作区并使其感觉像你自己的(或者在我的情况下,像 Wes Bos 的)。

了解文件

既然我们进入了代码模式,让我们看一下我们将要处理的文件。我将借用 create-guten-block 自述文件中的内容作为参考。

└── test-block
  ├── plugin.php
  ├── package.json
  ├── README.md
  |
  ├── dist
  |  ├── blocks.build.js
  |  ├── blocks.editor.build.css
  |  └── blocks.style.build.css
  |
  └── src
     ├── block
     |  ├── block.js
     |  ├── editor.scss
     |  └── style.scss
     |
     ├── blocks.js
     ├── common.scss
     └── init.php

在本教程中,我们只关注 src 目录中的内容。我们不会触碰 dist(这些是编译后的文件)、plugin.php 或任何其他文件,例如 package.jsonpackage-lock.json.eslintignore

plugin.php 正式通知 WordPress 我们插件的存在。它需要 src/init.php,这是我们将为我们的区块编写任何 PHP 代码的地方。通常,我们不会在 plugin.php 中编写任何内容——默认情况下,它只包含注册插件的注释。

让我们深入了解 src

└── src
   ├── block
   |  ├── block.js
   |  ├── editor.scss
   |  └── style.scss
   |
   ├── blocks.js
   ├── common.scss
   └── init.php

block 目录包含单个区块的文件。这包括:

  • block/block.js——单个区块的所有 JavaScript 代码。
  • block/editor.scss——特定于编辑器视图的 Sass 部分。
  • block/style.scss——特定于前端视图的 Sass 部分,即你在查看页面/文章时看到的样式。

现在,打开 src/blocks.js

A screenshot of the contents of blocks.js showing a single line importing the file blocks/block.js

我认为 src/blocks.js 是区块的目录,类似于 Sass 项目结构中 index.scssmain.scss 的作用。如果我们想在我们的插件中包含两个区块——假设这是一个自定义区块套件——理论上,我们可以复制 block 目录,将其重命名,并向 src/blocks.js 添加如下内容:

import 'new-block/block.js';

然后,无论 create-guten-block 在幕后为我们准备了什么,它都会知道将我们新区块的 block.js 包含到编译到 dist 的主脚本文件中(如果你还没有,现在是查看 dist 的好时机)。

到目前为止还不错,对吧?我们还没有真正接触到任何 JavaScript 代码……

一个挑战!

好的,现在是时候来挑战一下了!打开 src/block/block.js,花几分钟时间阅读作者 Ahmad 优秀的注释。

然后,看看你是否能够弄清楚如何*

  1. 更改区块的名称,即在区块选择器中显示的名称。
  2. 更改区块的图标(❤ Dashicons)。
  3. 更改前端显示的文本,即当你“查看文章”时显示的文本。
  4. 更改后端显示的文本,即编辑器视图中显示的文本。
  5. 为前端视图设置 30px 的圆角。
  6. 为编辑器视图设置渐变背景。
  7. 使第一个段落标签中的文本可编辑。

* 你应该能够在大约 10 分钟内完成(几乎!)所有这些。;-)


怎么样?

你遇到了什么问题?你是否厌倦了重新加载编辑器?你是否看到“此区块似乎已在外部修改”的消息比你想要的次数更多?我确实遇到了,但新技术的现状就是这样——开发人员体验还有很多不足之处,但这目前不是团队的优先事项,将在 Gutenberg 计划开发的后期阶段进行改进。

最重要的是,你完成了 #7 吗?

如果你完成了,那么你应该来写这篇教程!那个问题确实是一个陷阱。我希望你至少感到有点困惑和好奇,因为这就是我们学习的方式!我们将在第 3 部分中讨论这个问题。

现在我们已经了解了基本情况,让我们更深入地探讨一下区块的概念。

区块的骨架

这是删除了注释的 block.js——我们可以称之为静态区块的骨架。

// Stripped down version of src/block/block.js

// PART 1: Import dependencies
import './style.scss';
import './editor.scss';

// PART 2: Setup references to external functions
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;

// PART 3: Register the block!
registerBlockType( 'cgb/block-test', {
  
  // Part 3.1: Block settings
  title: __( 'test - CGB Block' ),
  icon: 'shield',
  category: 'common',
  keywords: [
    __( 'test — CGB Block' ),
    __( 'CGB Example' ),
    __( 'create-guten-block' ),
  ],
  
  // PART 3.2: Markup in editor
  edit: function( props ) {
    return (
      <div>You’ll see this in the editor</div>
    );
  },
  
  // PART 3.3: Markup saved to database
  save: function( props ) {
    return (
      <div>This is saved to the database and returned with the_content();</div>
    );
  },
} );

让我们与另一个静态区块进行并排比较,即 Gutenberg 中包含的默认区块中的“分隔线”区块。该文件位于 packages/block-library/src/separator/index.js 中。如果你的文件夹在 VS Code 或 Sublime 中打开,可以使用 Mac 上的快捷键 Command + Option + 2 或“查看 > 分割编辑器”来并排显示文件。

如果你按照前面概述的文本编辑器设置进行操作,你应该会看到类似以下内容:

Side-by-side block.js files in VS Code — one side the block.js from create-guten-block, the other from the separator block in the Gutenberg library

在此图像中,我将上面简化的区块版本复制/粘贴到一个空文件中进行比较,而无需注释。这是可选的!

你注意到哪些相似之处?哪些差异?打开 gutenberg-master/library/ 内的其他几个区块目录,并查看其文件,将其与我们的区块骨架进行比较。花几分钟阅读代码,看看你是否能发现一些模式。

我注意到了一些模式:

  1. 在变量声明和函数参数中到处都是花括号。
  2. 标记出现在 return 语句中,并且通常包含虚构的标签名称(你可能会将这些识别为 React 组件)。
  3. 所有区块似乎都有一个 settings 对象,其中包含 titleiconcategory 等条目。在库区块中,它们出现在 export const settings = ... 对象中,而在我们的插件区块中,它们是 registerBlockType 的参数的一部分。
  4. 所有区块都具有 editsave 函数作为 settings 对象的一部分。
    • 函数的语法与我们区块的 editsave 函数略有不同。
      • edit( { className } ) { ... }separator/index.js 中。
      • edit: function(props) { ... } 在我们的 block.js 中。
    • 库区块似乎引用了 attributes 而不是 props
  5. 库中的所有区块都包含一个 index.js。有些包含 block.js 或其他似乎包含扩展 Component 的类的定义的文件,例如 class LatestPostsBlock extends Component { ...

你发现了什么?欢迎在评论中分享你的发现(但不要停止阅读!)。

一个简短但相关的切线

你可能已经注意到,在库中的每个 index.jsblock.js 文件中都有一个导入 @wordpress/i18n 的语句,以及在我们的插件的 block.js 中对 wp.i18n 的引用。i18n 代表国际化,就像 a11y 代表可访问性一样。国际化指的是开发应用程序以轻松翻译成其他语言的做法。由于我们希望为我们的区块中的所有静态文本做好翻译准备,因此为了简洁起见,我们将 wp.i18n 赋值给 __ 的别名,这与我们使用 $ 作为老式的 jQuery 的别名非常相似。在此处阅读更多关于 WordPress 的 i18n 的信息

还值得一提的是 wp.i18n 中的 wp 来自哪里以及为什么在 Gutenberg 源代码中将其引用为 @wordpress/i18nwp 是一个全局对象——全局表示一个在任何地方都可用的变量——包含 WordPress 所有公开可用的 JavaScript API 方法。为了演示这一点,请在 WordPress 管理员中的页面上打开控制台。键入 wp 并按 Enter 键。你应该会看到类似以下内容

Animated GIF showing the response object when wp is typed into the console

因此,每当我们引用 wp 对象中的某些内容时,我们所做的只是访问 WordPress JavaScript API 提供给我们的某些功能。Gutenberg 源代码中的 @wordpress/i18n 正在执行相同的操作,但它从 npm 模块而不是全局对象中导入函数。WordPress 核心开发人员有意将 wp 全局中的函数公开到公共 API 中,以便在主题和插件中使用。

如果你和我内心的批评者一样,你可能会想,“随便吧,Lara,我不关心这些细节。只要告诉我如何用现有的 JavaScript 创建一个酷炫的区块!”我会回答

在这个环境中,有 *太多* 的移动部件和新概念,我发现,我越认为代码是理所当然的,整个过程就越令人沮丧和耗时。带着好奇心对待每一行代码!如果你不知道它做什么,请在 Gutenberg 源代码中进行“在文件夹中查找”,看看你是否可以找到可以跟随的线索。至少对我来说,这比尝试用复制粘贴随意构建某些东西,是一种更愉快的处理不熟悉代码的方式。

屏幕录制

这是一个屏幕录制,我引导 Geoff Graham 了解我们在本文中介绍的概念。

作业

什么?作业?当然,有作业!在第 3 部分,Andy 🍉 将深入探讨现代 JavaScript 好东西:React、JSX 和 ES6 语法。虽然我们的系列文章是为那些相对较新的 JavaScript 用户编写的,但从许多不同的角度和资源学习代码和概念是有帮助的。

为了尽早介绍一些概念,以下是第 3 部分之前的一些“作业”大纲

1. 花一些时间(1-2 小时)学习 React 教程,或者直到你能用自己的话说出

  • React 中的 render 方法
  • JSX 以及那些虚构的标签名称映射到 JavaScript 函数
  • 为什么 React 使用 className 而不是 class

推荐资源

  • 我真的很喜欢 Lynda.com 上 Eve Porcello 的 学习 React.js。Lynda 是一项付费服务,但你可以在一些城市使用图书馆卡免费观看(当然,洛杉矶 可以)。
  • 我还推荐这个文章系列,Brandon Richey 的 使用 create-react-app 学习 React
  • 在 Youtube 上有 很多很多选项
  • 我一直在学习 Brian Holt 在 Frontend Masters(付费)上的 React 完全入门 课程,它非常好。
  • 我不能不提到 Wes Bos 的 React 初学者 课程(付费)——我自己还没有学习过,但我只听说过很好的评价,而且他一直在更新它!

我还建议阅读 CSS-Tricks 上 Kingsley Silas 的 从头开始了解 React 状态,因为它专门深入探讨了 React 中的状态。如果你刚接触 React,这将需要消化很多内容,但我认为即使它现在还不太理解,也值得尽快将其纳入你的大脑。


2. 理解 ES6 解构并找到一些在 Gutenberg 源代码和我们的插件中出现的例子(这并不难)。

推荐资源


3. 熟悉条件运算符或三元运算符。

一句话来说,三元运算符是 if...else 语句的简写。你将在整个 Gutenberg 源代码中看到这些——找到一些简单的示例,这些示例为字符串的值提供回退,以及更强大的用法,例如在 blocks/library/paragraph/index.js 中。

推荐资源

  • MDN 文章 非常好。
  • 还要了解非非运算符——这是一个关于它的 Stack Overflow 帖子
  • 不要在这个兔子洞里走得太远,但如果你非常有雄心壮志,可以研究一下 JavaScript 中的类型强制。FreeCodeCamp 上的 这篇文章 和 Kyle Simpson 的你不知道 JS 中的 这一章 是可靠的起点。

好的!非常感谢你的阅读,并在第 3 部分中期待 React、JSX 和其他好东西。

评论

本教程的任何部分是否有不清楚的地方?你在任何地方迷路了吗?我们希望不断改进它,因此,如果任何部分难以理解,或者任何信息不正确或过时,请告诉我们。

再次感谢,祝你好运!


文章系列

  1. 系列介绍
  2. Gutenberg 到底是什么?
  3. 使用 create-guten-block 的入门指南 (本篇)
  4. 现代 JavaScript 语法
  5. React 101
  6. S设置自定义 webpack
  7. 自定义“卡片”块