WordPress 7.1 图标注册 API 实战教程
Hands-on with the WordPress 7.1 Icon Registration API
WordPress 7.1 新增公开的 Icon Registration API,可通过 wp_register_icon_collection 和 wp_register_icon 注册图标集合与 SVG 图标。
文章从注册函数到完整插件逐步演示 WordPress 7.1 图标注册 API,并说明现有 SVG 元素和属性限制。
今年早些时候 WordPress 7.0 推出 Icon 区块时,那是我一段时间以来最令人兴奋的时刻之一。但它也多少让人有些失望,因为当时没有用于注册自定义图标的公开 API。对该区块的大多数创意用途而言,可选图标列表显得过于受限。
好消息是:公开 API 将随 WordPress 7.1 一同推出!
它几乎实现了我在项目中真正使用它所需的所有功能,比如我一直在尝试的这个餐厅菜单创意:

在本教程中,我会介绍其中的一些基础知识。随后,你将学习如何从头到尾构建一个完整的图标注册插件。
目录
- How to register icons
- 注册函数快速概览
- 图标集和图标示例
- Building an icon registration plugin
- 插件设置
- 在插件中打包图标
- 定义图标数据结构
- 向 WordPress 注册图标
- 加载插件文件并启动引导程序
- 输出图标
- The missing pieces: what you can’t yet do
- 元素允许列表
- Stroke 属性会被移除
- 尚无编辑器组件……
如何注册图标
本教程介绍了使用该 API 的入门知识,以及适用于大多数用例的相关部分。如需完整概览,请阅读《在 WordPress 7.1 中注册和渲染 SVG 图标》开发者说明。
注册函数快速概览
注册自定义图标时,你需要做两件事:
- 注册一个自定义图标集,或者确定要为哪些图标注册内容的现有图标集的 slug。
- 为特定图标集注册你的图标。
大多数插件和主题都需要自定义图标集,可以通过 wp_register_icon_collection() 函数注册:
wp_register_icon_collection( string $slug, array $args );该函数有两个参数,你需要为其传入参数:
$slug:插件中图标集的唯一键。理想情况下,应以插件或主题名称作为前缀(例如plugin-collection)。$args: An array of arguments for the collection:label:图标集的易读国际化标签,用于界面显示。description:描述该图标集的国际化字符串。
准备好图标集后,你可以使用 wp_register_icon() 注册单个图标:
wp_register_icon( string $icon_name, array $icon_properties );它也有两个参数:
$icon_name:图标的集合命名空间标识符。它必须以图标集 slug 开头,后跟/(例如plugin-collection/icon-slug)。$icon_properties: An array of arguments to define the icon:label:图标的国际化易读标签。content:图标的 SVG 标记(可选)。file_path:SVG 标记文件的文件路径(可选)。
content 和 file_path 各自都是可选参数,但实际注册图标时必须选择其中之一。
图标集和图标示例
在本教程的后续内容中,你将学习如何构建一个包含餐厅图标集的完整插件。不过,我们先用一个简短示例来演示如何使用刚刚介绍过的这些函数。
注册图标集和图标时,应在 init 钩子上执行。以下代码可添加到插件文件或主题的 functions.php 中,它会在 Restaurant 图标集下注册一个 Cake 图标:
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>'
]);
}代码使用了上面的 content 属性,而不是 file_path。对于一次性示例,前者可能更合适,因为它会展示完整代码。你将在下面的完整插件示例中使用 file_path 属性。
要测试已注册的图标集和图标,请在文章编辑器或站点编辑器中插入 Icon 区块,然后点击区块工具栏中的 替换按钮。随后你会看到 图标库,其中包含新的 Restaurant选项卡(即图标集):

选择 Cake 图标后,它会出现在 Icon 区块中,你可以使用现有的设计工具对其进行自定义。
生成的区块标记如下:
<!-- wp:icon {"icon":"devblog-restaurant/cake"} /-->如你所见,其中包含集合 slug 和图标 slug:devblog-restaurant/cake。你可以像使用其他任何区块一样,在模板或模式中使用这段标记。
就新开发功能而言,这项功能相当直接。对于 Icon Registration 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 文件的加载位置。在主题环境中,你可以跳过上述代码。
在插件中打包图标
在这个项目中,我使用了 Google 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 已经有枚举(enum)五年了(从 8.1 开始)。而在这种情况下,我更喜欢使用字符串支持的枚举,以获得编译时安全保障和自动补全。而且没有魔法字符串!
在插件的 src 文件夹中,创建一个名为 Icon.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 扩展名)。
你还需要为图标提供几项其他数据:
- 集合 slug:
devblog-restaurant。 - 插件中图标存储位置的绝对路径,即你之前添加的
PLUGIN_DIR常量加上public/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() 返回当前枚举用例的国际化文本标签。
接下来,为枚举添加一个 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 常量。
使用字符串支持的枚举而不是数组,可以让 Icon 具备编译时类型安全性和自动补全。例如,Icon::Cake 是一个真实、可检查的类型,PHP 会对其进行验证,IDE 也能自动补全;而类似 $icons['cake'] 的数组键只是一个字符串,拼写错误可能悄无声息地导致问题,直到运行时才会报错。
枚举还可以让行为与数据放在一起。像 label()、handle() 和 filePath() 这样的方法可通过 match 为每个枚举值定义一次。添加新图标意味着添加一个枚举值以及每个方法中的一行代码;如果某个枚举值未处理,PHP 的 match 会通过静态分析或运行时 UnhandledMatchError 向你发出警告。
枚举使有效图标的完整集合封闭、可发现且自带文档说明,而不是一组散落在各数组中的开放式“魔法字符串”。
向 WordPress 注册图标
既然你已经用代码获得了类型安全、对 IDE 友好的图标表示,剩下的就是让 WordPress 知道这些图标。你可以创建一个职责单一的小类,用于注册图标。
在 src 下创建一个新文件,命名为 IconRegistrar.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()
]);
}
}
}该类有一个 boot() 方法,调用时会在 WordPress 的 init 钩子上添加 register() 操作。随后,它会注册图标集合及各个图标。
由于你使用了字符串支持的枚举,因此可以直接使用内置的静态 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();
});现在,如果你查看之前看到的Icon Library → Restaurant选项卡,应该能看到已注册图标的完整列表:

输出图标
正如本文前面提到的,你可以在 Icon 块中通过名称引用已注册的图标:
<!-- wp:icon {"icon":"devblog-restaurant/cake"} /-->对于大型集合来说,这通常会带来糟糕的开发体验,因为你必须记住确切的字符串名称。如果该字符串存放在其他位置的普通数组中,也不会获得自动补全。
使用枚举后,你可以轻松解决这一问题,无需担心确切名称。为确保获得正确的 Cake 图标,请这样引用:
<!-- wp:icon {"icon":"<?= Icon::Cake->handle() ?>"} /-->如果你不在区块上下文中(例如使用经典主题,或以其他方式作为插件的一部分输出),可以使用 wp_get_icon() 函数:
<?= wp_get_icon(Icon::Cake->handle(), [
'size' => 32
]) ?>缺失的部分:目前还无法实现的功能
Icon Registration API 到现在已经非常强大,可以注册满足大多数需求的图标。但仍有一些限制会随 WordPress 7.1 一同推出。这些功能目前正在为 7.2 及更高版本积极开发。
元素允许列表
目前,SVG 图标仅允许使用 <svg>、<path> 和 <polygon> 作为元素,其他所有内容都会被清除。部分原因是 WordPress 目前尚未提供用于清理 SVG 的正式函数。这很可能是 7.1 中高度自定义图标所面临的最大限制因素。
目前正在通过一个 PR 着手解决这一限制。该 PR 在进行清理的同时,添加了一整套元素,例如 <circle>、<rect> 等。
描边属性会被清除
与上述清理工单相关,目前 stroke 并不是允许使用的属性,因此无法使用它为 SVG 设置样式。这意味着,目前定义图标颜色时应使用基于 fill 的图标。
此外,fill 会从外层 <svg> 中清除,但会保留在 <path> 和 <polygon> 上。其思路是,外层 SVG 元素应通过 CSS 设置样式(例如通过 Icon 区块或自定义 CSS)。
尚无编辑器组件……
Icon 区块是一个很好的起点,而正式的注册 API 让扩展程序能够实现更强大的功能。但如果说有什么是我更加期待的,那就是使用内置组件在其他区块内添加图标。
这方面正在进行实验性工作,以下是下个开发周期值得关注的工单:
- 将 IconPickerModal 移入 block-editor 以便重复使用
- 添加更多折叠导航图标选项
- 手风琴区块:区块使用加号而非 SVG 作为图标
- 详情区块:允许从一组图标中进行选择
当然,在 meantime,您始终可以自行构建自定义组件并完成集成。目前已有专用于图标的只读 REST API 端点。
感谢 @bph 和 @welcher 审阅本文。
来源:WordPress 开发者博客 · https://developer.wordpress.org/news/2026/08/hands-on-with-the-wordpress-7-1-icon-registration-api/
部分链接为推广/关联链接。