
Gutenberg 已发展成为一款功能强大且高度可定制的编辑器。除了其强大的开箱即用功能外,WordPress 开发者现在还可以利用丰富的 API 轻松地将自定义功能集成到他们的网站中。这种可扩展性实现了高度定制化的开发,使开发者能够打造高度个性化且功能丰富的在线体验。
本文探讨了两个鲜为人知但功能强大的 WordPress 开发功能:样式变体(也称为区块样式)和区块变体。
虽然它们的实用性乍一看可能有些晦涩难懂,但您会惊讶于它们的实用性,并且只需投入少量时间就能将它们无缝集成到您的工作流程中。
您将通过一个实际项目亲身体验它们的含义以及如何使用它们。您只需复制粘贴本教程中的代码,并最终添加自定义设置,即可在您的 WordPress 网站上实现此项目。
在深入研究项目之前,我们先快速回顾一下先决条件:
- 本地 WordPress 开发环境:任何环境都可以,但我们强烈推荐本地开发套件 DevKinsta。它易于使用,并提供许多设置和工具,可快速启动和管理本地 WordPress 网站。
- Node.js 和 npm:这些至关重要,因为区块编辑器基于 React 构建,需要构建过程。
- 基本的前端开发技能:对 Node.js、JavaScript(基于 React)、PHP 和 CSS 有基本的了解将大有裨益。
虽然这个项目并不复杂,但请做好编写一些代码的准备。完整的代码也可在 GitHub 上找到。
区块样式与区块变体
区块样式和区块变体是 WordPress 中两个强大的开发者功能。虽然它们的名称听起来很相似,但在用途和用法上却有所不同。
区块样式(也称为样式变体)是预先构建的 CSS 样式集,允许您通过单击更改区块的外观。注册区块样式后,块侧边栏中会出现一个按钮,用于为该区块分配一组预先构建的样式。您可以打开或关闭样式,并在编辑器中实时预览区块。

核心图像区块有两种默认样式变体。
样式变体不会改变区块的属性。它们仅通过为区块的封装元素分配 CSS 类来修改区块的外观。
区块变体是一个更强大的工具,因为它们允许您创建包含属性和内部区块的预配置区块版本。它们还会显示在编辑器的区块插入器中。本质上,区块变体在用户看来就像一个独立的区块,完全独立于构建它的区块。
区块变体允许自定义区块的外观、初始设置和结构。
考虑到所有这些,让我们利用这些工具将 Gutenberg 区块提升到一个新的水平!
核心图像区块上的动画宝丽来效果
现在,让我们深入研究我们的项目!我们将使用 Gutenberg 插件扩展核心图片区块,以实现以下功能:
- 实现宝丽来风格变体:用户只需在区块的设置侧边栏中单击一下,即可为图片添加迷人的宝丽来效果。
- 添加悬停动画:我们将使用精妙的悬停动画来增强宝丽来风格图片的效果。
- 创建“动画宝丽来”区块变体:这将允许用户直接从区块插入器快速插入带有悬停效果的预配置宝丽来图片。
准备好了吗?让我们开始设置插件!

图像区块上的动画效果
环境设置
开始之前,我们需要使用 Node.js 搭建一个 WordPress 开发环境。我们假设您已经安装了本地 WordPress 开发环境以及最新版本的 Node.js 和 npm。如果您需要帮助,请查看我们的教程,了解如何构建 Gutenberg 插件以向区块编辑器添加功能。
步骤 1 – 创建基本插件结构
在本教程中,我们将插件命名为 Image Hacker。
导航到您的 plugins 目录并创建一个新的 image-hacker 文件夹。在此文件夹中,创建一个新的 image-hacker.php 文件(插件的主文件)和一个 src 子文件夹,您将在其中构建插件的功能。
以下是您的插件的基本结构:
/wp-content/plugins/ └── /image-hacker/ ├── image-hacker.php └── /src/
步骤 2 – 创建PHP代码
接下来,您需要确保 WordPress 能够识别您的插件。为此,请将以下代码添加到 image-hacker.php:
<?php
/**
* Plugin Name: Image Hacker
* Description: Adds new features to the core Image block
* Version: 1.0.0
* Author: Your Name
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: image-hacker
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
步骤 3 – 初始化npm并安装依赖项
打开您常用的命令行工具,并导航到插件目录。到达那里后,运行以下命令:
npm init -y
此命令会初始化一个新的 package.json 文件,其中包含项目的依赖项和脚本。
接下来,您需要安装 WordPress 脚本以及 webpack 和 Babel 等构建工具:
npm install @wordpress/plugins @wordpress/scripts --save-dev
此命令添加一个包含节点依赖项的 node_modules 文件夹和一个 package-lock.json 文件。下图显示了 Visual Studio Code 中项目的当前结构:

Visual Studio Code 中的 Gutenberg 插件
接下来,打开 package.json 文件并更新 scripts 属性,如下所示:
{
"name": "image-hacker",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"@wordpress/plugins": "^7.25.0",
"@wordpress/scripts": "^30.18.0"
}
}
请注意,devDependencies 版本可能与上述版本不同,具体取决于您环境中实际安装的版本。
步骤 4 – 创建插件源文件
下一步是创建插件源文件。导航到 src 文件夹并添加以下文件:
index.jsstyle.scsseditor.scss
插件结构现在应该如下所示:
/wp-content/plugins/ └── /image-hacker/ ├── /node-modules/ ├── image-hacker.php ├── package.json ├── package-lock.json └── /src/ ├── index.js ├── style.scss └── editor.scss
现在打开您的 WordPress 管理面板并导航到插件屏幕。找到 Image Hacker 插件并激活它。
注:editor.scss 文件仅用于声明编辑器的区块样式,而 style.scss 文件则包含编辑器和前端的区块样式。在本项目中,我们不会使用 editor.scss 文件。
步骤 5 – 在插件文件中引入资源
接下来,您需要在主插件文件中引入插件资源。在 image-hacker.php 文件中添加以下内容:
/**
* Enqueue block editor assets.
*/
function image_hacker_enqueue_editor_assets()
{
$asset_file = include(plugin_dir_path(__FILE__) . 'build/index.asset.php');
// Enqueue the script with our modifications
wp_enqueue_script(
'image-hacker-script',
plugins_url('build/index.js', __FILE__),
array('wp-plugins', 'wp-edit-post'),
filemtime(plugin_dir_path(__FILE__) . 'build/index.js')
);
// Enqueue the editor-only styles
wp_enqueue_style(
'image-hacker-editor-style',
plugins_url('build/editor.css', __FILE__),
[],
filemtime(plugin_dir_path(__FILE__) . 'build/editor.css')
);
}
add_action('enqueue_block_editor_assets', 'image_hacker_enqueue_editor_assets');
/**
* Enqueue frontend and editor assets.
*/
function image_hacker_enqueue_assets()
{
$asset_file = include(plugin_dir_path(__FILE__) . 'build/index.asset.php');
// Enqueue styles for both frontend and editor
wp_enqueue_style(
'image-hacker-style',
plugins_url('build/style-index.css', __FILE__),
[],
filemtime(plugin_dir_path(__FILE__) . 'build/style-index.css')
);
}
add_action('enqueue_block_assets', 'image_hacker_enqueue_assets');
这段代码的作用如下:
enqueue_block_editor_assets动作钩子将index.js脚本和editor.css文件加入队列。enqueue_block_assets动作钩子将style.css文件加入队列。
请注意,这段代码包含位于插件 /build/ 文件夹中的 .js 和 .css 资源。这意味着,要使其正常工作,您需要在命令行工具中运行 build 命令:
npm run build
另请注意,当您将名为 style.scss 的文件导入 index.js 时,编译后的 CSS 文件将不再名为 style.css,而是 style-index.css。
注册区块样式
您已完成开发环境的设置。现在,您可以进入项目的精彩部分,注册您的区块样式变体。
注册区块样式的方法有很多种,您可以根据自己的目标和个人偏好进行选择。我们将使用 JS 方法构建 Gutenberg 插件。打开您的 /src/index.js 文件并粘贴以下代码:
// Import the function to register block styles.
import { registerBlockStyle } from '@wordpress/blocks';
// Import the function to run code only when the DOM is ready.
import domReady from '@wordpress/dom-ready';
// This line tells the build process to include and compile our SCSS file.
import './style.scss';
/**
* Use domReady to run code only when the DOM is ready.
*/
domReady(() => {
// Register our new style variation for the core image block.
registerBlockStyle('core/image', {
name: 'polaroid',
label: 'Polaroid',
});
});
结合使用 registerBlockStyle 和 domReady 可确保仅在 DOM 完全加载时注册样式变体。另请参阅官方文档。
选择 Polaroid 样式后,WordPress 会自动将 .is-style-polaroid 类添加到区块包装器中。
下一步是提供样式变体的 CSS。打开 /src/style.scss 文件并添加以下代码:
.wp-block-image.is-style-polaroid {
padding: 15px 15px 70px 15px;
background-color: white;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
max-width: 360px;
transform: rotate(-3deg);
transition: transform 0.3s ease-in-out;
figure {
margin: 0 !important;
}
img {
display: block;
width: 100%;
height: auto;
}
figcaption {
position: absolute;
bottom: 15px;
left: 0;
right: 0;
text-align: center;
font-family: 'Permanent Marker', cursive;
color: #333;
font-size: 18px;
}
}
保存代码,运行 npm run build,然后跳转到 WordPress 信息中心。创建一个新文章或页面并添加图片。选择图片后,点击区块侧边栏中的“Styles”标签,然后选择“Polaroid”。

图片区块的新样式变体
添加图片说明文字,保存文章,然后在前端查看效果。您应该会看到一张带有精美斜体标题的宝丽来风格图片。

带有 is_style_polaroid 类的 figure 元素
注:由于选择器的高度特异性,某些属性(例如 max-width )可能无法在编辑器中应用。如果您需要在编辑器中应用这些属性,您可能需要在 editor.scss 文件中添加适当的样式。
构建逻辑
下一步是构建图像动画的逻辑。我们将使用 CSS 的 transform 属性创建一个简单的动画。首先,将以下代码区块添加到 src/style.scss 文件:
.wp-block-image.is-style-polaroid.has-image-animation:hover {
transform: rotate(0deg) scale(1.05);
}
这段代码确保仅当区块是宝丽来图像且通过工具栏切换按钮应用了 has-image-animation 类时,才会应用悬停效果。
现在,您需要将 CSS 类添加到图像容器(即 figure 元素)的逻辑。为此,您需要一些过滤器和回调函数。
首先,将以下行添加到您的 src/index.js 文件:
import { addFilter } from '@wordpress/hooks';
步骤 1. 向Image区块添加新属性
您将使用 addFilter 来操作核心 Image 区块。首先,向 Image 区块添加一个新的 imageAnimation 属性:
function addImageAnimationAttribute( settings, name ) {
if ( name !== 'core/image' ) {
return settings;
}
settings.attributes = {
...settings.attributes,
imageAnimation: {
type: 'boolean',
default: false,
},
};
return settings;
}
addFilter(
'blocks.registerBlockType',
'image-hacker/add-image-animation-attribute',
addImageAnimationAttribute
);
回调函数 addImageAnimationAttribute 接受两个参数:
settings– 当前区块属性的数组name– 指定要修改其属性的区块的名称。
然后,该函数返回更新后的属性数组。
步骤 2. 向图像区块添加切换控件
接下来,您需要向图像区块工具栏添加一个控件以启用动画。
首先,将以下导入添加到 index.js 文件:
import { createHigherOrderComponent } from '@wordpress/compose';
import { Fragment } from '@wordpress/element';
import { BlockControls } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
然后在文件末尾添加如下代码:
const withPolaroidControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.name !== 'core/image') {
return <BlockEdit {...props} />;
}
const { attributes, setAttributes, isSelected } = props;
const { imageAnimation, className, lightbox } = attributes;
return (
<Fragment>
<BlockEdit {...props} />
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="format-image"
label={__('Toggle Animation', 'image-hacker')}
isActive={imageAnimation}
onClick={() =>
setAttributes({ imageAnimation: !imageAnimation })
}
/>
</ToolbarGroup>
</BlockControls>
</Fragment>
);
};
}, 'withPolaroidControls');
addFilter(
'editor.BlockEdit',
'image-hacker/with-polaroid-controls',
withPolaroidControls
);
这段代码的作用如下:
createHigherOrderComponent函数创建一个高阶组件 (HOC),该组件包装了BlockEdit,BlockEdit 是编辑器中负责显示区块的主要组件。- HOC 会拦截该组件并检查它是否为图像区块。这确保所有编辑操作都只应用于图像区块。
- 我们使用解构赋值从
props和attribute对象中提取所需的属性 (Property) 和特性 (Attribute)。 - 我们使用
BlockControls、ToolbarGroup和ToolbarButton组件向区块工具栏添加一个“切换动画 (Toggle Animation)”按钮。 isActive设置imageAnimation的默认状态。onClick切换imageAnimation的值。

区块工具栏上已添加一个自定义按钮。
现在您有了一个属性和一个按钮。但是,如果您点击该按钮,什么也没有发生。
步骤 3. 将CSS类添加到包装元素
下一步是将 has-image-animation 类应用于包裹图像的 figure 元素。为此,您需要一个过滤器,以便您在前端将 CSS 类分配给图像。
将以下代码附加到 index.js 文件:
function addAnimationFrontendClass(extraProps, blockType, attributes) {
if (blockType.name === 'core/image' && attributes.imageAnimation) {
extraProps.className = `${extraProps.className || ''} has-image-animation`;
}
return extraProps;
}
addFilter(
'blocks.getSaveContent.extraProps',
'image-hacker/add-animation-frontend-class',
addAnimationFrontendClass
);
当 imageAnimation 属性设置为 true 时,此代码会动态地将 CSS 类 has-image-animation 添加到 figure 元素。
让我们尝试了解具体发生了什么。
addFilter会挂接到编辑器的进程中,以修改数据或行为。blocks.getSaveContent.extraProps是我们要定位的特定钩子。extraProps是一个特殊的钩子,可让您向包装器元素添加额外的 HTML 属性。image-hacker/add-animation-class是过滤器的唯一名称。addAnimationFrontendClass是每次运行block.getSaveContent.extraProps钩子时执行的回调函数的名称。此函数接受 3 个参数:extraProps:包含区块包装器元素属性的对象,例如className。blockType:包含区块详细信息的对象,例如其name(core/image)。attributes:区块属性对象。
- 该函数的逻辑确保代码仅在
blockType.name === 'core/image'且attribute.imageAnimation为true时运行。 - 如果两个条件都成立,该函数将返回一个新的
props对象,并将has-image-animation附加到现有的类对象上。
现在,您可以亲自尝试一下。在您的内容中添加一张图片,从区块侧边栏中选择宝丽来风格,然后点击区块工具栏中的“Toggle Animation(切换动画)”按钮。保存您的文章并在前端检查结果。当您将鼠标悬停在图片上时,图片应该会旋转。

已将 is_style_polaroid 和 has_image_animation CSS 类添加到图片区块
注册区块变体
区块变体是区块的预配置版本,具有一组属性和嵌套区块。WordPress 将区块变体视为独立区块,使其在区块插入器中可用,并使用自定义图标标记。
您可以使用区块变体创建一个默认应用 Polaroid 样式的新版本图片区块。
第一步是将 registerBlockVariation 函数导入到您的 /src/index.js 文件中:
import { registerBlockStyle, registerBlockVariation } from '@wordpress/blocks';
然后在 domReady() 内部的 registerBlockVariation 函数中添加对 registerBlockStyle 下方的调用:
domReady(() => {
// Register a style variation for the image block.
registerBlockStyle('core/image', {
name: 'polaroid',
label: 'Polaroid',
});
// Register a block variation of the image block
registerBlockVariation('core/image', {
name: 'animated-polaroid',
title: 'Animated Polaroid',
icon: 'image-filter',
attributes: {
className: 'is-style-polaroid',
imageAnimation: true,
},
scope: ['inserter'],
});
});
registerBlockVariation 函数为现有区块创建变体。它接受两个参数:区块名称和定义变体的对象。(另请参阅区块变体简介和区块变体 API 文档。)
保存文件,运行构建程序以应用更改,然后返回 WordPress 管理员页面。创建新文章,并在区块插入器中搜索“Animated Polaroid”区块。

区块插入器中的区块变体
注:由于环境的复杂性和选择器的特殊性,我们不会在区块编辑器中添加生成动画的代码。因此,动画在编辑器中无法正常工作。
测试和调试
让我们进行一些测试。在新文章中添加一张或多张图片。为每张图片选择宝丽来风格,启用动画并添加链接。同时,使用图库区块运行测试。
一切似乎都按预期运行。但是,将带有灯箱效果的链接添加到宝丽来风格的图片上,效果并不理想。
这种奇怪的行为似乎是由于 WordPress 灯箱效果和 CSS 过渡之间的兼容性问题造成的。
为了避免漫长而复杂的调试过程,您可能需要禁用“点击放大”选项,并添加警告以通知用户灯箱已禁用。
首先,您需要导入一些额外的资源。以下是从 /src/index.js 文件导入的资源的完整列表:
import { registerBlockStyle, registerBlockVariation } from '@wordpress/blocks';
import domReady from '@wordpress/dom-ready';
import { addFilter } from '@wordpress/hooks';
import { createHigherOrderComponent } from '@wordpress/compose';
import { Fragment, useEffect } from '@wordpress/element';
import { InspectorControls, BlockControls } from '@wordpress/block-editor';
import { PanelBody, Notice, ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useDispatch } from '@wordpress/data';
import './style.scss';
我们添加了以下导入:
useEffect来自@wordpress/element。(参见文档)InspectorControls来自@wordpress/block-editor(参见文档)。PanelBody和Notice来自@wordpress/components(参见文档)。useDispatch来自@wordpress/data。(参见 WordPress 开发者博客)。
现在将 withPolaroidControls 函数修改如下:
const withPolaroidControls = createHigherOrderComponent((BlockEdit) => {
return (props) => {
if (props.name !== 'core/image') {
return <BlockEdit {...props} />;
}
const { attributes, setAttributes, isSelected } = props;
const { imageAnimation, className, lightbox } = attributes;
const isPolaroid = className?.includes('is-style-polaroid');
const { createNotice } = useDispatch('core/notices');
useEffect(() => {
if (isPolaroid && lightbox?.enabled) {
// Disable the lightbox to prevent the conflict.
setAttributes({ lightbox: { ...lightbox, enabled: false } });
// Show the user a temporary 'snackbar' notice.
createNotice(
'warning', // The type of notice (info, success, warning, error)
__('Lightbox disabled for Polaroid style.', 'image-hacker'),
{
type: 'snackbar',
isDismissible: true,
}
);
}
}, [isPolaroid, lightbox]);
return (
<Fragment>
<BlockEdit {...props} />
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="format-image"
label={__('Toggle Animation', 'image-hacker')}
isActive={imageAnimation}
onClick={() =>
setAttributes({ imageAnimation: !imageAnimation })
}
/>
</ToolbarGroup>
</BlockControls>
{isSelected && isPolaroid && (
<InspectorControls>
<PanelBody title={__('Polaroid Style', 'image-hacker')}>
<Notice status="info" isDismissible={false}>
{__(
'The "Expand on click" (lightbox) feature is disabled for this style to prevent visual conflicts.',
'image-hacker'
)}
</Notice>
</PanelBody>
</InspectorControls>
)}
</Fragment>
);
};
}, 'withPolaroidControls');
useEffect是一个 React Hook,它“允许你将组件与外部系统同步”。该代码在组件渲染完成后以及每次依赖项数组[isPolaroid, lightbox]中的值发生变化时执行。仅当用户应用或移除宝丽来样式,或者激活或停用灯箱时,才会运行检查。(请参阅 React 文档。)- 条件
if (isPolaroid() && lightbox.enabled)确保仅当图像具有宝丽来样式且灯箱选项启用时,代码才会执行。 - 如果条件为
true,则灯箱将被禁用,并显示临时警告通知。(另请参阅通知数据参考。) - 条件
isSelected && isPolaroid会在图像区块工具栏中生成一个新面板,通知用户灯箱已被禁用。与 Snackbar 不同,此面板显示永久警告。

单击放大选项已被禁用。
小结
在本教程中,我们通过一个实际项目的视角,深入探讨了 WordPress 区块编辑器中一些最令人兴奋、最强大的开发者功能:我们扩展了核心图片区块,使其具备开箱即用的功能,并添加了自定义样式和动画效果。
我们采用渐进式增强方法,为图片区块设计了区块样式变体。这让用户可以轻松地将图片赋予经典的宝丽来风格。
接下来,我们在图片区块的工具栏中添加了一个专用按钮,方便用户创建引人入胜的悬停动画效果。
最后,我们创建了一个区块变体,并默认应用了宝丽来样式和动画设置,为整个教程画上了圆满的句号。
我们希望您从本教程中获得的见解和技巧能够帮助您为 Gutenberg 的核心区块创建出一些真正令人惊喜的自定义功能!
Happy coding!


评论留言