loicpennamen/icons-bundle

为 Twig 模板添加快速图标功能。支持字体或 SVG 图标。

安装: 4

依赖项: 0

建议者: 0

安全: 0

类型:symfony-bundle

v1.2.0 2024-08-10 16:43 UTC

This package is auto-updated.

Last update: 2024-09-10 16:51:29 UTC


README

🚀 快速在 Twig 中插入网络字体或 SVG 图标。
👍 保持应用程序中图标的视觉一致性。

为什么选择这个组件?

问题

无论您使用的是类似 Font AwesomeFlaticon 的字体图标,还是您自己的 .svg 图标... 在您的 Twig 模板中集成每个图标的源代码可能很麻烦,而且难以维护。

此外,有时一位开发者为某个上下文选择了一个图标,而另一位开发者使用了一个不同的图标来表示相同的上下文。例如,为了表示 "删除" 操作,开发者 1 可能会选择一个 垃圾桶 图标 🗑️,而开发者 2 可能会选择一个 叉号 图标 ❌,从而导致视觉不一致。

解决方案

此组件提供了一个名为 icon() 的 Twig 函数,用于在清晰的上下文中插入您的图标。

{{ icon('delete') }}

这将生成以下 HTML 片段

<i class="fi fi-rs-trash-bin"></i>

此组件允许您为每个上下文定义一个 图标。您可以将 上下文 定义为定义 "图标用于什么" 的 字符串。例如 userdashboardwarning 等。上下文在 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() 函数处理多个方法来显示图标,以下是它们的优先级顺序

  1. 上下文相关: 如果传递给 icon()key 存在于上下文列表中,则显示上下文图标。
  2. SVG: 如果任何指定的文件夹中存在文件,其 key 为文件名(减去 .svg 扩展名),则将其显示。
  3. 任意: 如果前一步失败,将显示图标字体模板,其中 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 测试