社区新闻

使用区块绑定构建书评网站,第1部分:自定义字段与区块变体

查看官方原文 ↗ 发布于

想象一下,你的代理机构刚刚接手了一位新客户。这位客户运营着一个需要全面改造的书评网站。他们需要为每本书添加一些自定义字段,例如评分、作者、页数以及指向 Goodreads 的链接。

你的代理机构也正在从传统的 WordPress 开发模式,转向全面拥抱区块编辑器所提供的所有功能。但项目要求不允许你为客户端需要的每一处元数据和自定义项都构建自定义区块。你需要一个更高效的解决方案。

这正是区块绑定 API 的用武之地。我在之前的两篇文章中已经介绍了该 API 的基础知识:

但区块绑定的真正威力在于与 WordPress 内部各种其他 API 和系统(如区块变体、模式等)的结合。一旦开始将它们组合起来,你在区块系统之上所能实现的潜力几乎是无限的。

那么,让我们一起为你客户的书评网站打下基础。然后,我将让你接手并进行微调。

先决条件

本教程将涵盖大量内容,如果详细解释每一行代码,会变得过于复杂。因此,你至少需要对以下概念有初步了解。本系列的目标是展示如何协同使用 WordPress 中的各种 API。

  • Node 和 npm: 你必须在本地机器上安装 Node.js 和 npm 才能学习本教程。
  • JavaScript 编程: 你应具备阅读、编写和理解中级 JavaScript 所需的基础知识
  • 区块编辑器开发: 你应该对构建在 WordPress 区块编辑器 中运行的代码感到得心应手。
  • 主题开发: 你应该能够构建一个区块主题,从其 functions.php 文件开始工作,并设置构建过程
  • 构建工具: 你必须知道如何从命令行界面 (CLI) 编写命令,例如 npm run <command>

设置项目

对于这个项目,你将创建一个名为 TT4 Book Reviews 的 Twenty Twenty-Four 子主题。这样你就不必为了启动项目而重新创建主题的每个部分。你可以通过其代码库查看完整构建的示例。

如果你想查看最终结果,这里有一个使用 WordPress Playground 的在线演示

在 WordPress Playground 中运行的示例站点截图。显示了一个首页,其中有三本书以列的形式展示。

文件结构

在你的 /wp-content/themes 目录中创建一个名为 tt4-book-reviews 的新文件夹。同时,在你的主题内添加以下子文件夹和文件:

  • /patterns
  • /public
  • /resources
    • /js
      • editor.js
      • meta.js
      • query.js
      • variations.js
  • /templates
  • functions.php
  • package.json
  • style.css
  • webpack.config.js

这看起来可能很多,但你将要添加的大多数文件代码量都很少。它们只是为了特定目的而分开。

主样式表和 functions 文件

因为你将此项目构建为默认 Twenty Twenty-Four 主题的子主题,所以你首先需要在主题文件夹中创建 <a href="https://developer.wordpress.org/themes/core-concepts/main-stylesheet/">style.css</a> 文件并添加文件头,以便 WordPress 识别它。

将以下代码添加到你的 style.css 文件中:

/*!
 * Theme Name:        TT4 Book Reviews
 * Description:       A child theme for a book review site.
 * Version:           1.0.0
 * Template:          twentytwentyfour
 * Tags:              full-site-editing
 * Text Domain:       themeslug
 * Tested up to:      6.5
 * Requires at least: 6.5
 * Requires PHP:      7.4
 * License:           GNU General Public License v2.0 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 */

在本教程中,你还将使用 <a href="https://developer.wordpress.org/themes/core-concepts/custom-functionality/">functions.php</a>,所以最好也设置好这个文件。

将以下代码添加到你的主题的 functions.php 文件中:

<?php
// Add your custom code below here.

现在,访问 WordPress 管理后台的外观 > 主题屏幕,找到你新建的TT4 Book Reviews主题并激活它。

构建脚本

本教程需要一些 JavaScript,所以在早期阶段设置构建过程也是个好主意。这个过程之前在超越区块样式,第1部分:在主题中使用 WordPress 脚本包中有深入介绍。主题手册中的构建过程文档也有描述。

打开你主题的 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"
	}
}

现在,通过命令行程序导航到你计算机上的 wp-content/themes/tt4-book-reviews 目录,并输入以下命令来安装必要的包:

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

你的 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/icons": "^9.46.0",
		"@wordpress/scripts": "^27.6.0",
		"path": "^0.12.7",
		"webpack-remove-empty-scripts": "^1.0.4"
	}
}

要让构建过程与你的主题协同工作,你还需要完成一个步骤,那就是设置主题的 webpack 配置文件。对于本教程,你只需要用它来构建编辑器脚本。

打开你主题的 webpack.config.js 文件,并添加以下代码:

const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' );
const path = require( 'path' );

module.exports = {
	...defaultConfig,
	...{
		entry: {
			'js/editor':  path.resolve( process.cwd(), 'resources/js', 'editor.js'   )
		},
		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
			} )
		]
	}
};

注册自定义字段

在考虑将自定义字段连接到区块之前,你必须首先注册要使用的每个元键。对于这个书评网站,我们坚持使用你的客户需要的四个字段:

  • themeslug_book_author 书籍作者姓名。
  • themeslug_book_rating 用户对书籍的星级评分。
  • themeslug_book_length 书籍的页数。
  • themeslug_book_goodreads_url 指向 Goodreads.com 上书籍页面的 URL。

确定了元键之后,是时候通过标准的 register_meta() 函数来注册它们了。将以下代码添加到你的主题的 functions.php 文件中:

add_action( 'init', 'themeslug_register_meta' );

function themeslug_register_meta() {
	register_meta( 'post', 'themeslug_book_author', [
		'show_in_rest'	    => true,
		'single'            => true,
		'type'              => 'string',
		'sanitize_callback' => 'wp_filter_nohtml_kses'
	] );

	register_meta( 'post', 'themeslug_book_rating', [
		'show_in_rest'      => true,
		'single'            => true,
		'type'              => 'string',
		'sanitize_callback' => 'wp_filter_nohtml_kses'
	] );

	register_meta( 'post', 'themeslug_book_length', [
		'show_in_rest'      => true,
		'single'            => true,
		'type'              => 'string',
		'sanitize_callback' => 'wp_filter_nohtml_kses'
	] );

	register_meta( 'post', 'themeslug_book_goodreads_url', [
		'show_in_rest'      => true,
		'single'            => true,
		'type'              => 'string',
		'sanitize_callback' => 'esc_url_raw'
	] );
}

为了让这些字段与区块绑定 API 协同工作,你需要确保每个已注册的元键的以下两个参数都设置为 true

  • show_in_rest 这是自定义字段能够通过 REST API(区块编辑器使用)使用的必要条件。
  • single 区块绑定 API 目前不支持单个键的多个元值,因此需要将其设置为单个值。

问题与解决方案:将自定义字段连接到区块

WordPress 6.5+ 默认支持通过 core/post-meta 绑定源将自定义字段连接到区块。这意味着你无需担心通过区块绑定 API 注册任何东西。

但是,正如区块绑定介绍,第1部分:连接自定义字段中所述,将绑定区块插入编辑器的唯一方法是手动切换到代码编辑器视图并键入区块标记。

例如,下面是将 themeslug_book_author 自定义字段绑定到段落区块时的标记示例:

<!-- wp:paragraph {
	"metadata":{
		"bindings":{
			"content":{
				"source":"core/post-meta",
				"args":{
					"key":"themeslug_book_author"
				}
			}
		}
	}
} -->
<p></p>
<!-- /wp:paragraph -->

而输入自定义元值的唯一方法是启用自定义字段面板并手动键入键和值:

WordPress 文章编辑器,显示了自定义字段面板。它显示了各种与书籍相关的元字段供用户输入。

作为一个有信誉的开发者,你绝不会想把这种体验交给客户,并要求他们完成所有这些工作。但这些限制在区块绑定 API 的第一个版本中是预料之中的。在 WordPress 6.5 发布之前,没有足够的时间来构建 UI 和完善用户体验。

作为一个开发者,你能做些什么来开始使用——我指的是真正使用——这个 API 来处理你将交给客户的实际项目呢?这就是我试图通过本教程系列回答的问题,接下来的部分将深入探讨解决方案。

使用区块变体插入绑定区块

如果你能像插入任何其他区块一样插入绑定区块,而无需编辑代码,会怎样? 你完全可以通过区块变体 API注册一个变体来实现这一点。

区块变体只不过是一个区块的替代版本,具有与原始区块不同的一组默认属性。而绑定区块只是一个定义了 metadata.bindings 属性的区块。

这意味着可以将这两个概念结合起来。例如,你可以在此截图中看到代表你之前注册的自定义字段的变体:

WordPress 文章编辑器,显示了一篇书评文章。左侧,区块插入器面板已打开,并高亮了“书籍作者”区块变体。

每次想要绑定区块属性时,你无需手动键入区块标记,而是可以设置一个变体来插入它,就像插入任何其他区块一样。这对你和你的客户来说都会轻松得多。

为绑定区块注册变体

要集成绑定和变体,你必须通过 JavaScript 注册你的变体(PHP 注册方法不支持此技术所需的 isActive() 检查)。

如果你还没有这样做,请在命令行程序中输入以下命令来启动构建过程:

npm run start

这将在你之前创建的 /public 文件夹下生成项目所需的构建文件。

在深入 JavaScript 之前,你必须首先在编辑器中排队加载你新生成的 /public/js/editor.js 文件。将以下代码添加到你的 functions.php 文件中:

add_action( 'enqueue_block_editor_assets', 'themeslug_editor_assets' );

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

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

现在,将以下代码添加到 /resources/js 目录下的 editor.js 文件中,以导入空的 variations.js 脚本:

import './variations';

有了这段代码,你就可以开始为你想要绑定到自定义字段的任何区块注册自定义变体。在本教程中,你将把每个自定义字段绑定到单个区块属性:

自定义字段区块属性
themeslug_book_authorParagraphcontent
themeslug_book_ratingParagraphcontent
themeslug_book_lengthParagraphcontent
themeslug_book_goodreads_urlButtonurl

当然,你可以将自定义字段绑定到项目中所需的任意数量的区块。

首先,打开你的 variations.js 文件,添加以下代码以导入你需要的依赖项并定义一个 Goodreads 图标:

import { registerBlockVariation } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import { page, pencil, starFilled } from '@wordpress/icons';

const goodreadsIcon = (
	<svg width="24" height="24" viewBox="0 0 24 24" version="1.1">
		<path d="M17.3,17.5c-0.2,0.8-0.5,1.4-1,1.9c-0.4,0.5-1,0.9-1.7,1.2C13.9,20.9,13.1,21,12,21c-0.6,0-1.3-0.1-1.9-0.2 c-0.6-0.1-1.1-0.4-1.6-0.7c-0.5-0.3-0.9-0.7-1.2-1.2c-0.3-0.5-0.5-1.1-0.5-1.7h1.5c0.1,0.5,0.2,0.9,0.5,1.2 c0.2,0.3,0.5,0.6,0.9,0.8c0.3,0.2,0.7,0.3,1.1,0.4c0.4,0.1,0.8,0.1,1.2,0.1c1.4,0,2.5-0.4,3.1-1.2c0.6-0.8,1-2,1-3.5v-1.7h0 c-0.4,0.8-0.9,1.4-1.6,1.9c-0.7,0.5-1.5,0.7-2.4,0.7c-1,0-1.9-0.2-2.6-0.5C8.7,15,8.