loicpennamen / icons-bundle
为 Twig 模板添加快速图标功能。支持字体或 SVG 图标。
Requires
- php: >=7.4
- symfony/framework-bundle: >=6.2
This package is auto-updated.
Last update: 2024-09-10 16:51:29 UTC
README
🚀 快速在 Twig 中插入网络字体或 SVG 图标。
👍 保持应用程序中图标的视觉一致性。
为什么选择这个组件?
问题
无论您使用的是类似 Font Awesome 或 Flaticon 的字体图标,还是您自己的 .svg 图标... 在您的 Twig 模板中集成每个图标的源代码可能很麻烦,而且难以维护。
此外,有时一位开发者为某个上下文选择了一个图标,而另一位开发者使用了一个不同的图标来表示相同的上下文。例如,为了表示 "删除" 操作,开发者 1 可能会选择一个 垃圾桶 图标 🗑️,而开发者 2 可能会选择一个 叉号 图标 ❌,从而导致视觉不一致。
解决方案
此组件提供了一个名为 icon()
的 Twig 函数,用于在清晰的上下文中插入您的图标。
{{ icon('delete') }}
这将生成以下 HTML 片段
<i class="fi fi-rs-trash-bin"></i>
此组件允许您为每个上下文定义一个 图标。您可以将 上下文 定义为定义 "图标用于什么" 的 字符串
。例如 user
、dashboard
、warning
等。上下文在 config/icons.yaml
下的单个文件中定义。这样,每次您需要 用户 图标并使用 {{ icon('delete') }}
时,应用程序中的视觉将保持一致。
参数
key
(string
):上下文或标识图标的任意键。template
(string
,可选):字体图标的模板,或 .svg 图标的集合。classes
(string
,可选):字体图标标签的附加类,或 .svg 包装器。
安装
请确保已全局安装 Composer,如 Composer 文档的 安装章节 所述。然后,打开命令行,进入您的项目目录并执行
composer require loicpennamen/icons-bundle
对于不使用 Symfony Flex 的应用程序,通过将其添加到项目 config/bundles.php
文件中注册的组件列表中来启用组件
// config/bundles.php
return [
// ...
LoicPennamen\IconsBundle\LoicPennamenIconsBundle::class => ['all' => true],
];
如何与图标字体一起使用
包含字体
此组件处理后端逻辑。您可以根据自己的喜好包含图标字体。网上有各种图标字体,一些常见选项包括
对于大多数解决方案,您可以选择以下方式之一
- 使用 CDN
- 下载字体文件并通过 CSS 包含它们
- 使用 NPM 包管理器。
阅读专门的文档以获取更多信息。在本文档中,我们将使用 Flaticons 作为示例。以下是 Flaticons 的文档。
在以下示例中,我们使用了 Flaticon 的 NPM 包,并在 Sass 文件中包含了字体
# Install the files
npm i @flaticon/flaticon-uicons
// app.scss
// With flaticons, each file defines a different style and shape:
@import "~@flaticon/flaticon-uicons/css/regular/straight.css"; // regular straight
@import "~@flaticon/flaticon-uicons/css/solid/rounded.css"; // solid rounded
@import "~@flaticon/flaticon-uicons/css/brands/all"; // Brand icons
配置上下文
创建一个名为 config/packages/icons.yaml
的文件来保存您的配置。
为了视觉一致性,您希望在每个上下文中使用相同的图标。如上所示,上下文 是一个 string
,它定义了“图标的使用目的”。例如,一个 "删除" 按钮不应该在某个地方显示垃圾桶,在其他地方显示禁止标志,在其他地方显示十字架……上下文允许通过在整个应用程序中使用的唯一 string
来定义要使用的图标。
以下是如何定义上下文的示例
# config/packages/icons.yaml
icons:
contexts:
# Use any context key you want, but dots & spaces are forbidden!
# context: "font key"
delete: "trash" # We choose Flaticon "trash" icon for deletion everywhere
cancel: "undo" # We choose Flaticon "undo" icon for cancellation everywhere
danger: "triangle-warning"
error: "triangle-warning" # Different contexts can use the same icon
menu: "burger-menu"
上下文可以分层以更好地组织
层次结构必须使用点作为 icon()
函数中的分隔符。层次结构可以深入到所需程度,但通常两级就足够了。例如,使用以下配置,您可以编写 icon('user.profile')
或 icon('alert.warning')
# config/packages/icons.yaml
icons:
contexts:
user:
profile: "user"
dashboard: "stats"
impersonate: "refer"
alert:
info: "info-cirle"
warning: "exclamation-triangle"
error: "exclamation-triangle"
任意方法
上下文的使用不是强制的。 例如,如果不配置上下文,您仍然可以使用函数 icon('xxxx')
,只要字体中存在键 xxxx
。这被称为 任意 方法。例如,以下代码片段
{{ icon('kangaroo') }}
生成以下 HTML 代码,无论字体是否有键名为 kangaroo
<i class="fi fi-rs-kangaroo"></i>
配置字体模板
默认配置下,函数 icon('user')
生成以下 HTML 代码
<i class="fi fi-rs-user"></i>
这只适用于您包含了来自 Flaticon 的非常具体的字体,具有直角和常规粗细。对于不同的图标集合或设计,您想要更改使用的 HTML 模板。
您可以配置多个模板并在 icon()
函数中选择一个。列表中的第一个模板用作默认模板。字符串 [KEY]
将由函数中传递的上下文值(或任意键)替换。字符串 [CLASSES]
将由函数传递的第三个参数替换。
# config/packages/icons.yaml
icons:
templates:
# @see https://npmjs.net.cn/package/@flaticon/flaticon-uicons
default: "<i class='fi fi-rs-[KEY] [CLASSES]'></i>" # Flaticons regular straight style
solid: "<i class='fi fi-ss-[KEY] [CLASSES]'></i>" # Flaticons regular solid style
以下是一个针对 Font Awesome 的配置示例
# config/packages/icons.yaml
icons:
templates:
# @see https://fontawesome-docs.npmjs.net.cn/web/add-icons/how-to
duotone: "<i class='fa-duotone fa-solid fa-[KEY] [CLASSES]'></i>" # Font-awesome duotone (by default as first of the list)
solid: "<i class='fa-solid fa-[KEY] [CLASSES]'></i>" # Font-awesome solid
sharp: "<i class='fa-sharp fa-solid fa-[KEY] [CLASSES]'></i>" # Font-awesome sharp
#...
如何使用 SVG 图标
配置
icon()
函数还可以显示 SVG 文件。由于它们在服务器端处理,因此您不需要将它们放在 public
文件夹中。默认情况下,函数在以下文件夹中查找 .svg 文件
/assets/svg/icons/<key>.svg
/public/svg/icons/<key>.svg
/public/build/svg/icons/<key>.svg
您可以使用 svg_paths
选项覆盖此列表
# config/packages/icons.yaml
icons:
svg_paths:
- '/assets/custom-svg-icons/'
- '/assets/brand-svg-icons/'
如果这两个目录中的任何一个存在文件,它将使用具有 svg-icon
类的包装 span 进行渲染
<span class="svg-icon"><!-- SVG file content --></span>
SVG 文件集合
您还可以命名目录以创建不同的 集合。例如,您可能有一个分为两个版本(即 浅色 和 深色)的 SVG 图标集合。如果每个集合(即文件夹)中的图标具有相同的文件名,您可以按如下设置配置
# config/packages/icons.yaml
icons:
svg_paths:
light: '/assets/svg-icons/light/'
dark: '/assets/svg-icons/dark/'
使用此配置,icon()
函数的第二个参数将是包含 SVG 文件的集合(即文件夹)
{# show a light SVG user icon, in the first directory of the list by default #}
{{ icon('user') }}
{# show a light SVG user icon #}
{{ icon('user', 'light') }}
{# show a dark SVG user icon #}
{{ icon('user', 'dark') }}
样式
您可能想要在应用程序中添加一些额外的 CSS,以确保正确显示您的 SVG 图标。例如
.svg-icon svg{
/* Contain the icon into font dimensions */
width: 1rem;
height: 1rem;
/* Fix the icon alignment */
position: relative;
bottom: .1rem;
}
自定义 SVG 包装器
如果您想更改围绕 SVG 内容生成的 HTML,请覆盖 svg_template
选项。模板中必须包含字符串 [SVG]
,以便在文件内容需要插入的位置。
icons:
svg_template: '<span class="my-icon-class [CLASSES]">[SVG]</span>'
方法优先级
由于 icon()
函数处理多个方法来显示图标,以下是它们的优先级顺序
- 上下文相关: 如果传递给
icon()
的key
存在于上下文列表中,则显示上下文图标。 - SVG: 如果任何指定的文件夹中存在文件,其
key
为文件名(减去 .svg 扩展名),则将其显示。 - 任意: 如果前一步失败,将显示图标字体模板,其中
key
的值为任意值,从而允许使用字体集中的任何图标,而不需要使用上下文。
如何获取可用图标的列表?
如果你正在从事某种内容编辑工作,你可能需要创建一个图标选择器。
目前没有现有方法可以检索字体中包含的所有图标的列表 - 即列出所有 任意 图标键。然而,可以通过类 LoicPennamen\IconsBundle\Services\IconsService
中的 getList()
方法列出 上下文 和 SVG 图标。
它返回一个遵循以下约定的项目数组
array(13) {
[0] => array(3) {
["key"] => "cancel"
["type"] => "font"
["collection"] => NULL
},
[1] => array(3) {
["key"] => "test"
["type"] => "svg"
["collection"] => "light"
}
}
可选参数 $sortBy
允许根据任何项目值对结果进行排序。默认情况下,项目按其 key
值的字母顺序排序。以下是一个使用示例
<?php
// src/Controller/IconController.php
namespace App\Controller;
// ...
use LoicPennamen\IconsBundle\Services\IconsService;
class IconController extends AbstractController
{
// ...
public function chooseIcon(IconsService $iconsService): Response
{
$choices = $iconsService->getList();
return $this->render('choose-icon.html.twig', [
'choices' => $choices
]);
}
}
{# /templates/choose-icon.html.twig #}
<b>Icons :</b>
<ul>
{% for choice in choices %}
<li>
{{ icon(choice.key) }}
{{ choice.key }}
</li>
{% endfor %}
</ul>
路线图
这个包未来可能会升级,以下是即将到来的变化
- 清理键:抛出错误或禁止字符
- 优化:为 SVG 图标设置缓存,而不是在每次调用
icon()
时读取每个文件夹。添加一个用于清除缓存的控制台命令和缓存持续时间选项。 - 设置 PHPUnit 测试