社区新闻

超越区块样式,第二部分:为分隔符区块构建自定义样式

查看官方原文 ↗ 发布于

欢迎回来!本系列教程的第二部分将教你如何从主题内部使用自定义控件扩展区块。

错过了第一部分? 请先查看超越区块样式,第一部分:在主题中使用 WordPress 脚本包。然后回到这篇文章继续学习。

本三部分系列的第二部分将引导你设计一个显示表情符号图标的自定义分隔符区块样式。在第三部分,我们将为该样式构建一个表情符号图标选择器。

WordPress文章编辑器,高亮显示了一个分隔符区块。工具栏中有一个弹出模态框,包含一个表情符号图标网格供选择。

启动引擎

在第一部分,你学习了如何将 WordPress 脚本包集成到你的主题中。请记住,在编写自定义 CSS/SCSS 和 JavaScript 时,你需要启用监视模式。这样,你才能确保编译后的代码最终会出现在 /public 文件夹中。

启动你最喜欢的命令行工具,导航到你的主题文件夹。然后运行以下命令:

npm run start

回归基础:创建区块样式

在深入构建自定义编辑器控件之前,让我们先退一步,使用区块样式 API 来构建图标样式。

是的,我能隔着屏幕听到你的疑问:如果我们要构建自定义控件,为什么还要先注册区块样式?

主要原因是这是开发过程中的自然环节。在为区块创建新功能时,我几乎总是从将它们构建为自定义区块样式开始。

通常,在特定项目中做到这一步就足够了。当你需要超越区块样式时,你可能直到问题变得明显才会意识到这一点——至少对我来说是这样。

从区块样式 API 开始的其他原因包括:

  • 区块样式 API 有其明显的局限性,这使得构建自定义控件的理由变得非常清晰。我们将一起跨越这条界限。
  • 你上次用 JavaScript 注册区块样式是什么时候?有一段时间了吗?你曾经做过吗?(许多优秀的 WordPress 主题开发者也没有做过。)
  • 你将带着一些基础代码离开本次学习,并在第三部分中继续构建。但在此之前,你就可以使用它,并了解如何在你自己的项目中使用它。

使用 JavaScript 注册区块样式

添加自定义图标

在开发过程中,我喜欢做的一件事是将正在构建的功能的各个部分模块化。这使得查找和将来修改更容易。整洁的代码更易于长期维护。

首先,在 resources/js 下创建一个 const.js 文件。现在这个文件夹应该如下所示:

  • resources/
    • js/
      • const.js
      • editor.js

你将使用 const.js 来存储其他文件可以导入的常量。目前,它将保存一个名为 ICONS 的图标定义数组。

继续将以下代码添加到文件中:

export const ICONS = [
	{ value: 'floral-heart',   icon: '❦' },
	{ value: 'blossom',        icon: '🌼' },
	{ value: 'sun',            icon: '☀️' },
	{ value: 'feather',        icon: '🪶' },
	{ value: 'fire',           icon: '🔥' },
	{ value: 'leaves',         icon: '🍃' },
	{ value: 'coffee',         icon: '☕' },
	{ value: 'beer',           icon: '🍻' },
	{ value: 'lotus',          icon: '🪷' },
	{ value: 'melting-face',   icon: '🫠' },
	{ value: 'guitar',         icon: '🎸' },
	{ value: 'pencil',         icon: '✏️' },
	{ value: 'rocket',         icon: '🚀' },
	{ value: 'clover',         icon: '☘️' },
	{ value: 'star',           icon: '⭐' },
	{ value: 'sunflower',      icon: '🌻' },
	{ value: 'beach-umbrella', icon: '⛱️' }
];

顶部的命令 export const ICONS 正如你所想:它导出了方括号之间的对象数组。

最终,每个对象将生成一个如下所示的 CSS 类:.is-style-icon-{value}

注册区块样式

要使用你的自定义图标,请将它们导入到 resources/js/editor.js。你还需要导入一些 WordPress 函数:

// Internal dependencies.
import { ICONS } from "./const";

// WordPress dependencies.
import { registerBlockStyle } from '@wordpress/blocks';
import domReady               from '@wordpress/dom-ready';
import { __, sprintf }        from '@wordpress/i18n';

注册区块样式非常简单:只需将你的值插入 registerBlockStyle()。请前往区块编辑器手册了解更多关于区块样式 API的信息。

请注意,下面的代码等待 DOM 准备就绪,然后遍历每个图标并将它们注册为区块样式:

// Register a block style for each icon.
domReady( () => {
	ICONS.forEach( ( icon ) =>
		registerBlockStyle( 'core/separator', {
			name: `icon-${ icon.value }`,
			label: sprintf( __( 'Icon: %s', 'theme-slug' ), icon.icon )
		} )
	);
} );

保存文件。webpack 将编译它。

现在创建一个新的文章或页面,并添加一个分隔符区块。它应该看起来像这样:

WordPress文章编辑器,包含一个分隔符区块。侧边栏中列出了20个独立的区块样式。

你还没有添加任何自定义 CSS,所以这些样式实际上都不起作用。目前,只需确保你可以在侧边栏的样式面板中看到区块样式。

你可能已经意识到区块样式系统正在达到极限。你现在在侧边栏有 20 个自定义样式——你的 17 个加上三个默认样式。用户界面根本不是为此而设计的。

显然,是时候构建一个自定义控件了。

设计图标分隔符

为了让图标区块样式呈现我设想的设计,CSS 必须做到以下几点:

  • 必须居中图标。CSS flexbox 和文本对齐使这变得非常简单。
  • 背景线需要继承用户选择的背景颜色或渐变。为了实现这一点,CSS 必须覆盖 WordPress 对 background 简写属性的使用。
  • 必须隐藏图标后面的部分线条,使线条看起来像是被图标分成了两半。你将使用 Twenty Twenty-Three 中的 base 颜色预设作为图标背景。

打开你主题的 resources/scss/screen.scss 文件,并添加基础区块样式代码:

hr.wp-block-separator[class*=is-style-icon] {
	display: flex;
	justify-content: center;
	border: none;
	text-align: center;
	overflow: visible;
	width: 100% !important;

	// Use `!important` to overrule core's use of the `background` shorthand.
	background-color: transparent !important;
	background-repeat: repeat-x !important;
	background-position: 0% 50% !important;
	background-size: 100% 2px !important;

	// Don't use `!important` for the background image, which allows user-
	// selected background gradients to work.
	background-image: linear-gradient( 90deg, currentColor, currentColor );

	// Styles the icon.
	&::before {
		// floral-heart default icon.
		content: var( --separator-icon, "2766" );
		padding: 0 0.5em;
		font-size: var( --wp--preset--font-size--large );
		line-height: 1;
		background-color: var( --wp--preset--color--base );
	}

	// If parent has background color, inherit down to the icon background.
	:where( .has-background[class*=-background-color] ) &,
	:where( .has-background[class*=-background-color] ) &::before {
		background-color: inherit !important;
	}
}

现在为每个自定义区块样式类分配其自定义图标。你注意到上面有一个名为 --separator-icon 的 CSS 自定义属性了吗?你可以用它来覆盖图标。

在同一个 screen.scss 文件中,为每个图标添加一个样式规则,将符号或表情符号分配给 --separator-icon 变量:

.is-style-icon-blossom        { --separator-icon: "🌼"; }
.is-style-icon-sun            { --separator-icon: "☀️"; }
.is-style-icon-feather        { --separator-icon: "🪶"; }
.is-style-icon-fire           { --separator-icon: "🔥"; }
.is-style-icon-leaves         { --separator-icon: "🍃"; }
.is-style-icon-coffee         { --separator-icon: "☕"; }
.is-style-icon-beer           { --separator-icon: "🍻"; }
.is-style-icon-lotus          { --separator-icon: "🪷"; }
.is-style-icon-melting-face   { --separator-icon: "🫠"; }
.is-style-icon-guitar         { --separator-icon: "🎸"; }
.is-style-icon-pencil         { --separator-icon: "✏️"; }
.is-style-icon-rocket         { --separator-icon: "🚀"; }
.is-style-icon-clover         { --separator-icon: "☘️"; }
.is-style-icon-star           { --separator-icon: "⭐"; }
.is-style-icon-sunflower      { --separator-icon: "🌻"; }
.is-style-icon-beach-umbrella { --separator-icon: "⛱️"; }

你的图标现在应该在编辑器中工作了:

WordPress文章编辑器,包含演示文本,段落之间由具有独特表情符号图标的分隔符区块分隔。

再看一眼。你可能第一次没有注意到,但这个截图与本文顶部指定的目标截图还不匹配。

缺少了什么? 目标截图中的图标后面有渐变背景线(好吧,是模拟的线)。但区块样式没有。

好消息是:CSS 可以处理用户选择的背景颜色和预设渐变:

WordPress文章编辑器,包含演示文本,段落之间由具有独特表情符号图标的分隔符区块分隔。向日葵图标被高亮显示,并具有自定义背景渐变。

你可以为每个图标的默认背景编写 CSS。但这会增加页面加载的负担,毫无理由地减慢速度。请不要这样做,尤其是在前端。

此外,分隔符区块已经有一个背景属性。你只是无法通过区块样式 API 访问它。

这个背景问题是区块样式系统的另一个限制——你只能用 CSS 控制你的区块样式。

相比之下,当你构建自定义控件时,你可以完全访问分隔符区块的任何属性——不仅仅是区块样式的 CSS 类。而这正是你将在本系列第三部分中要做的。你将为每个图标定义一个背景渐变,然后根据用户输入自动设置它。

为最后阶段做准备

在本教程系列的前两部分中,我们已经涵盖了很多内容。你学习了如何将 WordPress 脚本包集成到你的主题中,并已经看到了它的实际应用。你为分隔符区块构建了一些自定义图标样式,并看到了区块样式 API 的一些局限性。

第三部分,我们将把所有内容整合到一个单一的图标选择器控件中。

在本系列的最后一篇教程发布之前,我希望你做一件事:删除 resources/js/editor.js 文件中的所有代码。是的,全部。你不再需要它了。保留你添加到 resources/js/const.jsresources/scss/screen.scss 的内容。下次你将在这些文件的基础上继续构建。

在此之前,请随意摆弄你目前拥有的代码。玩得开心!