体验WordPress 7.1图标注册API
当WordPress 7.0今年早些时候推出图标块时,那是我一段时间以来最激动人心的时刻之一。但这也让我有些失望,因为没有公开的API来注册自定义图标。该方块可用的图标列表对大多数创意用途来说显得受限。
好消息是:公共API将随WordPress 7.1一起发布!
它几乎满足了我在项目中真正使用它所需的一切,比如我一直在琢磨的这个餐厅菜单创意:

在这个教程中,我会带你了解一些基础知识。然后你会学会从头到尾构建一个完整的图标注册插件。
如何注册图标
本教程涵盖了使用API的入门层面,以及大多数用例相关的部分。想了解完整情况,请阅读 WordPress 7.1 开发者说明中的注册与渲染 SVG 图标。
注册功能的简要概述
注册自定义图标时,你需要做两件事:
- 注册一个自定义图标集合,或者知道你想注册图标的现有集合的哪一个字符。
- 注册你的图标到特定系列。
大多数插件和主题都需要自定义集合,这些集合可以通过以下函数注册:wp_register_icon_collection()
wp_register_icon_collection( string $slug, array $args );
该函数有两个参数,你必须将参数传递给它们:
$slug:为你的收藏插件提供独特的密钥。理想情况下,这个名称会加上你的插件/主题名称(例如,)。plugin-collection$args:集合的参数数组:label:一个可读且国际化的集合标签,用于界面界面。description:一串国际化的字符串描述该收藏。
一旦你有了收藏,你将用来注册单个图标:wp_register_icon()
wp_register_icon( string $icon_name, array $icon_properties );
它还有两个参数:
$icon_name:一个集合命名空间的图标标识符。它必须以一个集合字条开始,后接一个(例如,)。/plugin-collection/icon-slug$icon_properties:定义图标的参数数组:label:一个国际化、人类可读的图标标签。content:图标的SVG标记(可选)。file_path:图标的SVG标记文件路径(可选)。
这两个都是可选参数,但你必须选择其中一个才能真正注册图标。contentfile_path
一个示例收藏与图标
在本教程后面,你将学习如何构建一个完整的餐厅图标集成插件。但我们先从一个简短的例子开始,展示你刚学到的函数如何运用。
注册集合和图标时,应该在挂钩上进行。以下代码,无论是添加到插件文件还是主题中,都会在餐厅集合下注册一个蛋糕图标:initfunctions.php
add_action('init', 'devblog_restaurant_icons_register');
function devblog_restaurant_icons_register(): void
{
wp_register_icon_collection('devblog-restaurant', [
'label' => __('Restaurant', 'devblog-restaurant-icons'),
'description' => __('Demo icons provided by the DevBlog Restaurant Icons plugin.', 'devblog-restaurant-icons')
]);
wp_register_icon('devblog-restaurant/cake', [
'label' => __('Cake', 'devblog-restaurant-icons'),
'content' => '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#1f1f1f"><path d="M160-80q-17 0-28.5-11.5T120-120v-200q0-33 23.5-56.5T200-400v-160q0-33 23.5-56.5T280-640h160v-58q-18-12-29-29t-11-41q0-15 6-29.5t18-26.5l56-56 56 56q12 12 18 26.5t6 29.5q0 24-11 41t-29 29v58h160q33 0 56.5 23.5T760-560v160q33 0 56.5 23.5T840-320v200q0 17-11.5 28.5T800-80H160Zm120-320h400v-160H280v160Zm-80 240h560v-160H200v160Zm80-240h400-400Zm-80 240h560-560Zm560-240H200h560Z"/></svg>'
]);
}
该代码使用上述属性而非。对于一次性的例子来说,这可能更好,因为它能显示完整的代码。你将在下面的完整插件示例中使用该属性。contentfile_pathfile_path
要测试已注册的集合和图标,请在帖子或网站编辑器中插入图标块,并在该块工具栏点击替换按钮。随后您将看到带有新餐厅标签页(即集合)的图标库:

选择蛋糕图标后,它会出现在图标块中,你可以用现有的设计工具进行自定义。
生成的区块标记如下:
<!-- wp:icon {"icon":"devblog-restaurant/cake"} /-->
如你所见,集合和图标字条都包含在内: 。你可以像使用其他方块一样,在模板或图案中使用这些标记。devblog-restaurant/cake
就新开发功能而言,这个相当直接。这就是大多数图标注册API使用时你需要知道的全部信息。
但让我们深入探讨在新API之上实际构建一个完整项目。
构建图标注册插件
如前所述,我有一个想法,想用图标做餐厅菜单页面。我知道在设计中点缀几个图标,会让读者更具视觉吸引力。
所以我来跟你讲讲我是怎么构建一个插件来添加这些图标的。所有代码分步骤展示,你也可以在其GitHub仓库中学习完整代码。
插件设置
和其他插件一样,你必须在下面创建一个新文件夹,并在里面放一个主插件文件。你还需要几个子文件夹来做这个项目。请创建一个插件目录,结构如下:wp-content/plugins
devblog-restaurant-icons/public/icon/
src/plugin.php
然后通过你喜欢的代码编辑器添加以下代码:plugin.php
<?php
/**
* Plugin Name: DevBlog: Restaurant Icons
* Plugin URI: https://github.com/wptrainingteam/devblog-restaurant-icons
* Description: WordPress 7.1+ demo plugin for registering icon collections.
* Version: 1.0.0
* Requires at least: 7.1
* Requires PHP: 8.1
* Author: Developer Blog
* Author URI: https://developer.wordpress.org/news
* License: GPL-3.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
* Text Domain: devblog-restaurant-icons
*/
declare(strict_types=1);
namespace DevBlog\RestaurantIcons;
# Prevent direct access.
defined('ABSPATH') || exit;
# Define the plugin constants.
const PLUGIN_DIR = __DIR__;
这些大多是制作插件的模板内容。但请注意一个常数;你以后会提到这个。PLUGIN_DIR
在编辑器中保持这个文件打开。你还会在本教程后面添加更多代码。
我把它做成插件,但你也可以通过主题注册图标。唯一的区别是图标SVG文件的加载点。你可以在主题上下文中跳过上述代码。
插件中的图标捆绑
在这个项目中,我使用了谷歌Material Icons库中的多个与食物相关的图标。你可以直接从那里拉取,或者直接从本项目的GitHub仓库文件夹获取列表。
拿到图标后,把它们放进插件里的文件夹里。你的文件夹结构应该是这样的:public/icon
icon/bakery.svgbento.svgbreakfast.svgbrunch.svgcake.svgdinner.svgkebab.svglunch.svgramen.svgrestaurant.svgrice-bowl.svgsoup-kitchen.svgtapas.svg
定义图标数据结构
在 PHP 中表示图标值的方法有很多种。你可以用普通数组、常量、生成像WordPress本身那样的图标清单(也是数组),或者在代码里包含大量调用。wp_register_icon()
我不喜欢那些方法。PHP 已经有五年的枚举(枚举)功能(自 8.1 版本起)。在这种情况下,我更倾向于使用字符串支持的枚举,以保证编译时安全和自动补全。而且,没有魔法线!
在你的插件文件夹里,创建一个新文件,并添加以下代码:srcIcon.php
<?php
declare(strict_types=1);
namespace DevBlog\RestaurantIcons;
enum Icon: string
{
case Bakery = 'bakery';
case Bento = 'bento';
case Breakfast = 'breakfast';
case Brunch = 'brunch';
case Cake = 'cake';
case Dinner = 'dinner';
case Kebab = 'kebab';
case Lunch = 'lunch';
case Ramen = 'ramen';
case Restaurant = 'restaurant';
case RiceBowl = 'rice-bowl';
case SoupKitchen = 'soup-kitchen';
case Tapas = 'tapas';
// Additional code for the enum goes here...
}
如你所见,每个枚举大小写代表你在上一步添加的一个图标文件名(不含扩展名)。.svg
你还需要为图标准备其他几项数据:
- 集合的蛞蝓:。
devblog-restaurant - 插件中图标存储的绝对路径,也就是你之前添加的常数 + 相对路径。
PLUGIN_DIRpublic/icon
在枚举定义中将这些作为常数加入:
public const COLLECTION = 'devblog-restaurant';
private const ICONS_PATH = PLUGIN_DIR . '/public/icon';
枚举在这种情况下还需要携带某种行为。如前所述,注册图标需要三项信息:名称、标签和SVG。所以这些东西都需要在枚举中等价地返回数据。Icon
首先,在枚举中添加一个新方法:label()
public function label(): string
{
return match ($this) {
self::Bakery => __('Bakery', 'devblog-restaurant-icons'),
self::Bento => __('Bento', 'devblog-restaurant-icons'),
self::Breakfast => __('Breakfast', 'devblog-restaurant-icons'),
self::Brunch => __('Brunch', 'devblog-restaurant-icons'),
self::Cake => __('Cake', 'devblog-restaurant-icons'),
self::Dinner => __('Dinner', 'devblog-restaurant-icons'),
self::Kebab => __('Kebab', 'devblog-restaurant-icons'),
self::Lunch => __('Lunch', 'devblog-restaurant-icons'),
self::Ramen => __('Ramen', 'devblog-restaurant-icons'),
self::Restaurant => __('Restaurant', 'devblog-restaurant-icons'),
self::RiceBowl => __('Rice Bowl', 'devblog-restaurant-icons'),
self::SoupKitchen => __('Soup Kitchen', 'devblog-restaurant-icons'),
self::Tapas => __('Tapas', 'devblog-restaurant-icons')
};
}
该方法的用途match()返回当前ENUM案例的国际化文本标签。
接下来,向枚举添加一个方法:handle()
public function handle(): string
{
return self::COLLECTION . '/' . $this->value;
}
因为图标名需要与集合名称一起命名,我们可以在这里直接在前面加上。所以每当你需要引用图标的完整句柄/名称时,都可以调用 。Icon::CaseName->handle()
最后,你需要一种方法将绝对文件路径引用到 SVG,所以在枚举中添加一个方法:filePath()
public function filePath(): string
{
return self::ICONS_PATH . '/' . $this->value . '.svg';
}
注意,如果在主题中构建,请使用 。根本不需要恒定。get_theme_file_path("public/icon/{$this->value}.svg")ICONS_PATH
使用支持的枚举代替数组,可以实现编译时的安全性和自动补全。例如,是真实且可检查的类型,PHP 验证它,IDE 也能自动补全;而数组键(如 Array 键)只是字符串,拼写错误,可以无声无误地破解直到运行时。IconIcon::Cake$icons['cake']
枚举还让行为与数据并存。像 、 和 这样的方法,每例通过 定义一次。添加新图标意味着每个方法只添加一个案例和一行,PHP 匹配系统会通过静态分析或运行时提醒你如果案件未处理。label()handle()filePath()matchUnhandledMatchError
枚举使所有有效图标成为封闭、可发现且自我文档化的,而不是分散在数组中的开放式“魔法字符串”集合。
用WordPress注册图标
现在你已经有了类型安全、IDE友好的代码图标表示,剩下的就是通知WordPress了。你可以用一个小班级来完成,他们唯一的责任就是注册图标。
创建一个名为 的新文件。然后添加以下代码:srcIconRegistrar.php
<?php
declare(strict_types=1);
namespace DevBlog\RestaurantIcons;
final class IconRegistrar
{
public function boot(): void
{
add_action('init', $this->register(...));
}
private function register(): void
{
// Register the collection.
wp_register_icon_collection(Icon::COLLECTION, [
'label' => __('Restaurant', 'devblog-restaurant-icons'),
'description' => __('Demo icons provided by the DevBlog Restaurant Icons plugin.', 'devblog-restaurant-icons')
]);
// Register icons for the collection.
foreach (Icon::cases() as $icon) {
wp_register_icon($icon->handle(), [
'label' => $icon->label(),
'file_path' => $icon->filePath()
]);
}
}
}
该类有一个方法,调用时会添加 WordPress 钩子上的动作。然后,它会同时注册图标集合和单个图标。boot()register()init
因为你用的是字符串背板枚举,所以你会得到内置的静态cases()免费的方法,它会返回你的图标案例数组。所以上述代码只需循环每个案例,并将每个自定义方法的结果传递到 。wp_register_icon()
另外要注意的是,代码在注册集合时无需记住那个字符串。不用担心打错字!Icon::COLLECTION
加载插件文件并启动
最后几项:加载你刚创建的PHP文件并调用该方法。IconRegistrar::boot()
在你的文件底部,添加以下代码:plugin.php
# Load classes manually. In production, use an autoloader.
require_once PLUGIN_DIR . '/src/Icon.php';
require_once PLUGIN_DIR . '/src/IconRegistrar.php';
# Bootstrap services.
add_action('plugins_loaded', static function (): void {
(new IconRegistrar())->boot();
});
现在如果你查看之前提到的图标库→餐厅标签页,应该能看到完整的注册图标列表:

出场图标
如本文前述所述,您可以通过图标块中的名称来引用已注册的图标:
<!-- wp:icon {"icon":"devblog-restaurant/cake"} /-->
对于大型集合来说,这通常是个糟糕的开发体验,因为你必须记住具体的字符串名。如果字符串存在于某个普通数组中,就没有自动补全功能。
有了枚举,修正起来很容易,不用担心具体名称。为了确保你得到正确的蛋糕图标,请像这样引用:
<!-- wp:icon {"icon":"<?= Icon::Cake->handle() ?>"} /-->
如果你不在块上下文(例如经典主题或以其他方式作为插件输出的一部分),你可以使用以下函数:wp_get_icon()
<?= wp_get_icon(Icon::Cake->handle(), [
'size' => 32
]) ?>
缺失的拼图:你还不能做到的
图标注册API现在非常强大,允许你注册大多数需求的图标。但 WordPress 7.1 仍然会有一些限制。这些功能正在为7.2版本及以后版本积极开发。
元素允许列表
目前,只有 、 和 被允许用于 SVG 图标的元素。其他一切都被剥离了。部分原因是WordPress目前还没有正式的SVG净化功能。这可能是7.1中高度自定义图标的最大限制因素。<svg><path><polygon>
目前正在进行永久居民的工作以解决这一限制。它添加了完整的元素集合,如 、 ,以及更多元素,同时对它们进行了净化处理。<circle><rect>
划画属性被剥离
与上述净化工单相关,目前不允许使用该属性,因此无法用它来样式SVG。这意味着你现在应该坚持用基于 的图标来定义你的图标颜色。strokefill
此外,从外部剥离,但存活于和。其理念是外部SVG元素应通过CSS样式(例如通过图标块或自定义CSS)进行样式化。fill<svg><path><polygon>
没有编辑器组件……还没
图标块是一个很好的开始,而一个合适的注册API让扩展器的功能更加强大。但如果说有什么让我更期待的,那就是用内置组件在其他方块内部添加图标。
该领域已有实验性工作,以下是下一个开发周期中值得关注的一些工作单:
当然,你随时可以自己构建一个自定义组件,并在此期间自己进行集成。有只读的 REST API 端点可用于图标。