社区新闻

超越区块样式,第一部分:在主题中使用 WordPress 脚本包

查看官方原文 ↗ 发布于

你是否遇到过这样的问题:你为 WordPress 提供的众多区块之一构建了一个很棒的区块样式。也许是为图片区块添加的渐变边框:

WordPress 文章编辑器内容画布中包含一幅山脉图片。图片带有橙色和紫色边框。

然后你又为胶带效果创建了另一种样式。再创建一个添加棕褐色滤镜的样式——你希望某些图片具有复古感。

很快你就会意识到,你可以混合搭配其中几种样式来创建独特的组合。

但有一个问题阻碍了你:WordPress 只允许你一次对一个区块应用一种样式。

为了解决这个问题,你可以轻松创建一些组合它们的额外样式。谁不想试试那个名为渐变边框带胶带和棕褐色滤镜的区块样式呢?

WordPress 文章编辑器内容画布中包含一幅山脉图片。图片顶部有一块胶带,使其看起来像是贴在墙上。图片带有棕色色调。

是的,这是个滑坡。不知不觉中,你就有几十个区块样式需要管理,每种组合都会增加更多开销并弄乱样式面板。我可不想让我的死敌有这种烦恼。

一定有更好的方法……

在本系列中,我们将踏上一段未知之旅——或者至少是未记录在案的——远远超越区块样式 API 的限制。旅程可能会很长,也许有点坎坷,但你和我安然无恙地到达彼岸——并掌握一些新技巧,用我们的主题施展样式魔法。

本系列的目标是教你如何使用区块开发者每天都能使用的 API。只不过,你将在主题中使用这些功能,而不是在区块中。并且你将使用符合 WordPress 主题目录指南的代码和技术。

那么,系好安全带。我们开始吧!

我们要构建什么?

当你想要在 UI 中构建一次性设计选项时,区块样式非常棒。你可以轻松地在 PHP 中使用 register_block_style() 或在 JavaScript 中使用 registerBlockStyle() 来注册它们。添加几行 CSS,你就有了一个全新的样式。

但让我们直说吧。样式 UI 面板是有限的。它是一个按钮列表。它们的名字在几个字符后就会被截断。而且你必须将鼠标悬停在上面才能看到预览:

WordPress 编辑器,内容画布中有一幅夜间海洋中的帆船图片。右侧边栏中,样式面板高亮显示,并展示了各种可供选择的区块样式。

我的意思是,我是个开发者。我想要更多。我想超越区块样式系统提供的有限用户体验。

如果这些样式有专门为用例定制的特定控件会怎样?例如,不是上面提到的渐变边框样式,而是让你的主题用户从任何已定义的渐变中选择?或者,不是棕褐色滤镜,而是拥有可以打开整个 CSS 滤镜规范的自定义控件?

你可以做所有这些事情——甚至更多。

在本教程系列中,你将学习如何为分隔符区块扩展一个像这样的表情符号图标选择器:

WordPress 文章编辑器,内容画布中选中了一个分隔符区块。工具栏有一个包含各种基于表情符号的图标的下拉列表。

图标选择器只是为了在你学习构建此控件的基础知识时保持趣味性。当你掌握了这些,你就可以用它做任何你想做的事情。

先决条件

我不会粉饰这一点:从能够用最少的编程构建基本主题,到能够让编辑器按你的意愿行事,存在一个技能跳跃。我不可能在这篇文章中涵盖你需要的所有基础知识。

在继续之前,你需要熟悉:

  • Node 和 npm:你必须在本地机器上安装 Node.js 和 npm才能跟上。
  • JavaScript 编程:你至少应具备阅读、编写和理解中级 JavaScript 所需的基础知识
  • 区块开发本系列将引导你了解必要的入门知识,但你需要足够熟练才能为自定义功能进行扩展。
  • 主题开发总的来说,你应该了解开发 WordPress 主题的基础知识,特别是使用 PHP。
  • CSS/SCSS:你将在 .scss 文件中编写一些代码,这些代码很容易转换为原生 CSS。
  • 构建工具:在大多数情况下,你应该熟悉从命令行界面运行命令,例如 npm run <command>。对 webpack 的基本了解也会很有用。

本教程系列中的所有代码示例都已在默认 Twenty Twenty-Three 主题的直接分支中进行了测试。创建你自己的分支并跟着操作将获得最佳体验,但如果你愿意,也可以从另一个区块主题开始工作。

设置你的主题以使用 WordPress 脚本包

让你的主题与编辑器对话的最重要部分是定义主题的资源结构,并导入使用编辑器构建所需的包。

完全有可能编写原生 JavaScript 或使用自定义系统。我走过那条路,并不有趣。当你使用 WordPress 提供的预构建工具时,你的生活会简单得多。

创建初始文件和文件夹来存放资源

命名很难。毫无疑问,你对自己的文件和文件夹有自己的命名方案。但为了让本教程有效,你需要使用我的方案。

考虑到这一点,将有两个顶级文件夹来存放主题的资源:

  • resources:你编写 CSS 和 JavaScript 代码的开发文件。
  • public:经过构建过程后的生产文件。

本教程之后,你可以使用你自己的系统。你需要确保更改文件引用。

现在在 /resources 文件夹内创建几个空白的 CSS 和 JavaScript 文件,使用下面的名称。你的结构应该如下所示:

  • resources
    • js
      • editor.js
    • scss
      • screen.scss
      • editor.scss

不用担心创建 /public 文件夹。构建过程会处理它。

安装 WordPress 脚本包

最初,@wordpress/scripts 包是为了简化区块构建过程而创建的。如今,它足够灵活,也可以与主题一起工作。即使你从未构建过区块,你也可以从中获得很多乐趣。

在你的主题中创建一个 package.json 文件,并向其中添加以下代码:

{
	"name": "your-project-name",
	"scripts": {
		"start": "wp-scripts start --webpack-src-dir=resources --output-path=public",
		"build": "wp-scripts build --webpack-src-dir=resources --output-path=public"
	}
}

scripts 下的 startbuild 命令只是你可以使用的可用脚本中的两个。你绝对应该深入研究其他脚本并使用它们。对于本教程,我们只需要这两个来启动构建过程并定义自定义源和输出目录。

现在打开你的命令行界面并导航到你的主题目录。输入此命令以安装必要的包:

npm install @wordpress/scripts path webpack-remove-empty-scripts --save-dev

@wordpress/scripts 包是与区块编辑器及其组件协作的基础。它还在不需要大量工作的情况下为我们提供了许多有用的工具。额外的 pathwebpack-remove-empty-scripts 包是你稍后将在 webpack 配置中使用的助手。

一旦你使用 --save-dev 标志执行了 npm install 命令,你的 package.json 现在应该将这三个包包含为开发依赖项

{
	"name": "your-project-name",
	"scripts": {
		"start": "wp-scripts start --webpack-src-dir=resources --output-path=public",
		"build": "wp-scripts build --webpack-src-dir=resources --output-path=public"
	},
	"devDependencies": {
		"@wordpress/scripts": "^26.8.0",
		"path": "^0.12.7",
		"webpack-remove-empty-scripts": "^1.0.3"
	}
}

主题 webpack 配置

如果配置 webpack 的想法听起来很可怕,别担心。我曾经也这样——说实话,大多数时候仍然如此。这里的大部分内容都是你可以复制、粘贴并稍作修改的样板文件。

其中最重要的部分是添加你的自定义入口点:你的 CSS 和 JS 文件的位置。

现在在你的主题中创建一个新的 webpack.config.js 文件,并向其中添加以下代码:

// WordPress webpack config.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Plugins.
const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' );

// Utilities.
const path = require( 'path' );

// Add any a new entry point by extending the webpack config.
module.exports = {
	...defaultConfig,
	...{
		entry: {
			'js/editor':  path.resolve( process.cwd(), 'resources/js',   'editor.js'   ),
			'css/screen': path.resolve( process.cwd(), 'resources/scss', 'screen.scss' ),
			'css/editor': path.resolve( process.cwd(), 'resources/scss', 'editor.scss' ),
		},
		plugins: [
			// Include WP's plugin config.
			...defaultConfig.plugins,

			// Removes the empty `.js` files generated by webpack but
			// sets it after WP has generated its `*.asset.php` file.
			new RemoveEmptyScriptsPlugin( {
				stage: RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS
			} )
		]
	}
};

这已经设置好了你之前定义的 CSS 和 JS 文件路径,所以你实际上不需要做任何其他事情,除非你打算自定义它。

你应该也注意到代码使用了 path 包来解析一些路径。而 webpack-remove-empty-scripts 插件在最后做了一些清理工作。本质上,它会删除原本会为你的样式表生成的空 JS 文件。

使用脚本包

至此,你已经完成了所有复杂的设置。现在让我们测试一下,确保它能工作。

打开计算机上的命令行程序,从你的主题目录运行 start 命令:

npm run start

这将构建你的文件的开发版本到 /public 文件夹下,看起来应该像这样:

  • public
    • js
      • editor.js
    • css
      • screen.css
      • editor.css

所有东西都整洁有序,我们主题作者喜欢这样,对吧? 

start 命令还会让你保持在“监视”模式。你可以直接对 /resources 下的资源文件进行任何代码更改,它们将在每次文件保存时被构建。你可以通过按键盘上的 Ctrl + C 退出此模式。

你添加到 package.json 中的 build 脚本将构建你的文件的生产版本。继续试试看:

npm run build

当然,你还没有任何代码,所以你实际上只是在构建空文件。但我们很快就会解决这个问题。

加载脚本和样式

如果你正在阅读本教程,你应该已经知道如何在 WordPress 中加载脚本和样式。但有一些事情你可能想要更改,所以不要跳过这部分。

使用 @wordpress/scripts 的好处之一是,它会自动为 webpack.config.js 中定义的每个入口点创建一个 {filename}.asset.php 文件。这个文件做了两件重要的事情:

  • 创建一个依赖项数组,因此你无需为脚本/样式调用手动定义它们。
  • 定义用于缓存清除的版本号。

这是一笔相当不错的交易,使得管理脚本和样式变得容易得多。 

打开你主题的 functions.php 文件(如果不存在则创建一个)。有三个不同的钩子需要你用来排队脚本和样式。 

首先,在你的网站前端排队加载主题的主样式表(称为 screen.css):

add_action( 'wp_enqueue_scripts', 'themeslug_assets' );

function themeslug_assets() {
	$asset = include get_parent_theme_file_path( 'public/css/screen.asset.php' );

	wp_enqueue_style(
		'themeslug-style',
		get_parent_theme_file_uri( 'public/css/screen.css' ),
		$asset['dependencies'],
		$asset['version']
	);
}

首先,代码将从 screen.asset.php 文件返回的数组分配给一个 $asset 变量。然后,它调用正常的 wp_enqueue_style() 函数来排队样式表。注意依赖项和版本是如何直接传递给函数的。

如果你希望你的样式在后端工作,你还必须向编辑器注册相同的样式表。你可以使用 add_editor_style() 函数(你不能向此函数传递依赖项或版本):

add_action( 'after_setup_theme', 'themeslug_editor_styles' );

function themeslug_editor_styles() {
	add_editor_style( [
		get_parent_theme_file_uri( 'public/css/screen.css' )
	] );
}

最后,你需要排队加载你的编辑器脚本和样式:

add_action( 'enqueue_block_editor_assets', 'themeslug_editor_assets' );

function themeslug_editor_assets() {
	$script_asset = include get_parent_theme_file_path( 'public/js/editor.asset.php'  );
	$style_asset  = include get_parent_theme_file_path( 'public/css/editor.asset.php' );

	wp_enqueue_script(
		'themeslug-editor',
		get_parent_theme_file_uri( 'public/js/editor.js' ),
		$script_asset['dependencies'],
		$script_asset['version'],
		true
	);

	wp_enqueue_style(
		'themeslug-editor',
		get_parent_theme_file_uri( 'public/css/editor.css' ),
		$style_asset['dependencies'],
		$style_asset['version']
	);
}

现在你已经准备好开始摆弄区块编辑器了。这会很有趣!

敬请期待下一篇文章

这感觉像是本系列第一部分的自然停靠点。你和我一起涵盖了很多内容。我们实际上还没有构建任何东西,但我们已经为接下来的步骤做好了充分准备。

我通常不布置作业,但花点时间玩玩这个设置。尝试编写一些基本的 CSS 或 JavaScript,感受一下一切是如何工作的。然后花几分钟阅读 @wordpress/scripts 文档

第二部分,你将学习设计一组自定义区块样式。第三部分将把所有内容整合成一个漂亮且功能齐全的编辑器控件。从那里开始,嗯,你将构建一些惊人的功能。

资源