如何在 WordPress 中使用区块变体

Avatar of Dmitry Mayorov
Dmitry Mayorov

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

WordPress 5.4 并非很久之前发布,除了其他改进和错误修复之外,它还引入了一项名为“区块变体”的功能。我最近在一个项目中使用了它,对该功能的智能程度感到惊喜。实际上,我认为它并没有得到应有的关注,因此我决定撰写本文。

什么是区块变体?

区块变体允许开发人员定义现有区块的实例。您将在下面看到的示例是一个引用区块。也许您的网站有三种不同的方式来显示引用。可以为每种方式创建一个区块变体,以便它们都以不同的方式进行样式设置。这听起来非常类似于区块样式,但变体的概念比这更进一步,正如我们将看到的。

区块变体与区块样式有何不同?

合理的问题。区块变体在插入器中显示为具有唯一名称(以及可选的)图标的单独区块,并且可以具有预填充的自定义属性和内部区块。

区块样式旨在更改区块的外观。实际上,区块样式是使用帖子编辑器中的区块选项向区块添加自定义类的一种花哨方法。

当您考虑如何在帖子编辑器中使用每个选项时,差异就很明显了。假设我们注册了一个名为“花哨引用”的新区块样式。我们通过扩展核心“引用”区块来做到这一点,例如来自 区块编辑器手册 的此示例

wp.blocks.registerBlockStyle(
  'core/quote',
  {
    name: 'fancy-quote',
    label: 'Fancy Quote'
  },
);

这会将 .is-style-fancy-quote 类添加到帖子编辑器中引用区块设置中。

Screenshot of the Block options in the WordPress post editor highlighting the options for a quote block. A "Fancy Quote" option is listed under Styles and the custom class name is in an Additional CSS Classes field.
我们现在在“样式”下的区块选项中有一个“花哨引用”选项,并为其填充了相应的类。

尽管它听起来像是会做相同的事情(从技术上讲它可以做到),但区块变体可用于预填充自定义属性(包括自定义类)和内部区块。它们实际上是作为单独的区块注册的。

让我们更仔细地看看 API 和区块变体可以做什么。

创建区块变体

注册区块变体的 API 与我们刚刚看到的区块样式非常相似

wp.blocks.registerBlockVariation(
  'core/quote',
  {
    name: 'fancy-quote',
    title: 'Fancy Quote',
  },
);

registerBlockVariation 函数接受区块的名称(在我们的例子中是 core/quote)和一个描述变体的对象(或对象数组)。

上面的代码默认情况下不会做太多事情,但它确实将“花哨引用”添加到可用区块列表中。

Showing the Fancy Quote variation in the WordPress Block Inserter.
我们现在有两个不同的“引用”区块可用于添加到帖子中。

要充分利用变体,我们需要在描述它的对象中提供更多详细信息。该列表在 Make WordPress 文章 中有介绍,但我会在这里分享它并提供其他注释。

  • name – 变体的唯一且机器可读的名称。根据 Github 和 Make 文章上的示例,可以假设最佳实践是使用 kebab-case 来命名变体。
  • title – 人类可读的变体标题。这是插入器图标下显示的内容。
  • description – 详细的变体描述。也显示在插入器中。如果为空,将使用默认的区块描述。(可选)
  • icon – 变体的图标。可以是 Dashicons slug、SVG 或对象。遵循与 registerBlockType 中相同的声明模式。(可选)
  • isDefault – 指示当前变体是否为默认变体。默认为 false。在我们的示例中,如果将其设置为 true,则花哨引用区块将是插入器中唯一可用的引用区块。(可选)
  • attributes – 覆盖区块属性的值。这些是特定于区块的。例如,您可以为标题区块设置 level 或为间隔符设置 height
  • innerBlocks – 嵌套区块的初始配置。仅适用于首先允许内部区块的区块,例如列、封面或组。我们将在其中一个示例中介绍这一点。(可选)
  • example – 示例为区块预览提供结构化数据。您可以将其设置为 undefined 以禁用为区块类型显示的预览。这与 registerBlockType 中的示例字段相同。(可选)有关此参数,请参阅 更多信息
  • scope – 变体适用的范围列表。如果未提供,则假定所有可用范围。可用选项包括 blockinserter。我们将在其中一个示例中详细介绍。

你们中的许多人可能想知道为什么我们需要这种额外的抽象层。我将尝试通过一些用例(来自我最近的一个项目)来回答这个问题。

用例:具有不同宽度的按钮

假设您的设计系统有两种类型的按钮:填充轮廓

Two buttons, one with a green fill and one with a green border. Both say Learn More.
设计系统中的填充和轮廓按钮样式

幸运的是,这些是 WordPress 中按钮的默认样式。无需注册任何新样式或修改编辑器。您只需为每种样式编写一些 CSS 即可。生活很美好,每个人都很快乐。

但是,您再次查看设计规范后发现有一些变化。按钮有三种宽度:常规全宽

The same green buttons but with additional variations at two different widths for a totally of six buttons.
具有不同宽度变体的填充和轮廓按钮样式

该死!您有点沮丧,因为您现在有两个选择

  1. 为新的按钮尺寸编写两个额外的类(例如,.is-wide.is-full),然后教客户使用编辑器中的高级面板添加这些类,并编写一本手册,说明每个类的作用。或者……
  2. 注册四个(!)新的样式,它们位于区块选项中:填充宽填充全宽轮廓宽轮廓全宽

这两个选项都不是很优雅。(顺便说一句,“填充全宽”到底是什么?真是一个不幸的词语!)

还有两个选项我没有列出

  • 过滤按钮区块并向其添加自定义宽度控件
  • 从头开始构建自定义区块。

对于这样一项简单的任务来说,这些显然感觉像是繁重的工作。

输入区块变体!通过添加仅两个变体,全宽我们可以保持简洁和简单

wp.blocks.registerBlockVariation(
  'core/buttons',
  [
    {
      name: 'wide',
      title: 'Wide Buttons',
      attributes: {
        className: 'is-wide'
      },
  },
  {
      name: 'full',
      title: 'Full Buttons',
      attributes: {
        className: 'is-full'
      },
    }
  ]
);

这与向按钮区块添加自定义类相同,但它以一种整洁且优雅的方式直接从区块插入器中添加到帖子中

Showing the Wide and Full button variations in the WordPress Block Inserter.
插入器中的按钮变体

生活很美好,每个人都再次快乐!**我们从这个例子中学到了什么?**

  • 它表明区块变体并非旨在取代区块样式。实际上,即使变体只是向区块添加一个类,它们也可以很好地协同工作。
  • 它演示了如何在单个声明中注册多个变体。

用例:重复的列布局

假设您是一位设计师,并且有一个包含案例研究的投资组合网站。每个案例研究都有一个介绍部分,其中包含项目名称、客户信息以及您在项目中的角色描述。它可能如下所示

Showing three columns, one that says Website Design, one that says Clients, and one says Role. Each one represents a column we want on the page.
工作类型(左)、客户(中)和您的角色(右)

问题在于,每次创建新的投资组合案例研究时,构建布局的这一部分都有些乏味——尤其是在客户我的角色标题永远不会改变的情况下。您只需要编辑主标题和两个段落。

使用区块变体,您可以创建一个核心区块的变体,称为项目简介,其中将预定义列和内部区块。此示例稍微复杂一些,因此我们将逐步构建它。

让我们从注册变体开始

wp.blocks.registerBlockVariation(
  'core/columns', {
    name: 'project-intro',
    title: 'Project Intro',
    scope: ['inserter'],
    innerBlocks: [
      ['core/column'],
      ['core/column'],
      ['core/column'],
    ],
  }
);

我们在这个例子中比第一个例子更进一步,所以为什么不从WordPress中内置的Dashicons库添加一个自定义的投资组合图标呢?我们使用icon属性来实现。

wp.blocks.registerBlockVariation(
  'core/columns', {
    name: 'project-intro',
    title: 'Project Intro',
    icon: 'portfolio',
    scope: ['inserter'],
    innerBlocks: [
      ['core/column'],
      ['core/column'],
      ['core/column'],
    ],
  }
);

这将使区块在区块菜单中以我们的图标显示。

Variation with a custom icon in the Block Inserter.

接下来重要的事情发生在添加内部区块的地方。

wp.blocks.registerBlockVariation(
  'core/columns', {
    name: 'project-intro',
    title: 'Project Intro',
    icon: 'portfolio',
    scope: ['inserter'],
    innerBlocks: [
      ['core/column'],
      ['core/column'],
      ['core/column'],
    ],
  }
);

但这只会给我们三个空的列。让我们在每个列中添加起始内容和内部区块。我们可以使用与在InnerBlocks组件中声明区块模板相同的模式。我们可以添加一个包含区块属性的对象作为数组中的第二个元素,以及一个包含内部区块的数组作为第三个元素。

第一列将如下所示

['core/column', {}, [
  ['core/heading', { level: 2, placeholder: 'Project Title'} ],
]]

…完整的区块变体如下所示

wp.blocks.registerBlockVariation (
  'core/columns', {
    name: 'project-intro',
    title: 'Project Intro',
    icon: 'portfolio',
    scope: ['inserter'],
    innerBlocks: [
      ['core/column', {}, [
        ['core/heading', { level: 2, placeholder: 'Project Title' }],
      ]],
      ['core/column', {}, [
        ['core/heading', { level: 3, content: 'Client' }],
        ['core/paragraph', { placeholder: 'Enter client info' }],
      ]],
      ['core/column', {}, [
        ['core/heading', { level: 3, content: 'My Role' }],
        ['core/paragraph', { placeholder: 'Describe your role' }],
      ]],
    ],
  }
);

酷,现在我们只需点击一下即可插入整个区块。好吧,是几次点击,但仍然比不使用变体快。

那么我们从这个例子中学到了什么?

  • 并演示如何在变体中使用内部区块。
  • 它展示了如何为变体定义自定义图标。

用例:四列布局

您已经知道列是一种默认的区块类型,并且有几种不同类型的列选项。四列布局不是其中之一,因此我们可以构建它。但这同时也引入了一个新概念:在区块变体的上下文中进行作用域

一些核心区块,例如,已经开箱即用地提供了变体。您可以在页面上插入区块之后选择其中一个。

Showing the columns block inserted with 5 different layout options to display up to 3 columns at varying widths.
区块作用域变体

假设您在网站上使用四列布局的频率与使用两列布局的频率一样高。这很不幸,因为没有快捷按钮可以创建四列布局。创建它有点烦人,因为在插入区块后需要额外点击才能到达列控件。

Showing the slider control to change the number of columns in the Block settings.

那么,您可以做些什么来改进此工作流程呢?没错,您可以添加一个区块变体来创建四列布局。与之前的示例相比,这次唯一的区别是,将此变体包含在区块占位符中,与所有其他列布局并排放置,更有意义。

这正是scope选项的作用。如果您将其设置为[block],则变体不会出现在区块插入器中,而是在插入区块后出现在变体中。

wp.blocks.registerBlockVariation(
  'core/columns', {
    name: 'four-columns',
    title: 'Four columns; equal split',
    icon: <svg ... />,
    scope: ['block'], // Highlight
    innerBlocks: [
      ['core/column'],
      ['core/column'],
      ['core/column'],
      ['core/column'],
    ],
  }
);
Four-column layout variation scoped to the block.
嘿,现在我们有了四列选项!

是不是很不错?!

我省略了图标的完整 SVG 代码,但如果您需要,它可以获取

总结一下scope:如果未声明,则变体将出现在区块插入器区块占位符中——特别是对于支持区块作用域变体的区块。

如果我们要从上面的示例中删除作用域参数,则变体将如下所示出现在插入器中

Four-column block variation in the block inserter.
请记住,区块内变体的图标大小和区块图标的大小不同。列的自定义图标 предназначен для作用域的区块,因此在这个例子中看起来有点格格不入。

那么我们从这个例子中学到了什么?

  • 它解释了区块和插入器作用域在变体中的区别。
  • 我们学习了如何使用 SVG 作为变体图标。

就是这样

如您所见,区块变体对于构建许多事物非常强大,从不同类型的按钮到完整的页面布局。

我想以快速回顾一下用于区块自定义的不同 API 以及何时使用它们来结束本文。

  • 如果需要更改区块的外观,并且添加 CSS 类足以实现此目的,则使用区块样式
  • 如果需要为区块指定默认属性和/或向其中添加内部区块,则使用区块变体
  • 如果这还不够,并且需要更改区块的标记,则可能需要考虑过滤区块或从头创建一个新的区块。

如果您有机会试用区块变体,请在评论中告诉我您对它们的看法!

资源