在主题中用自定义图标替换 Discourse 的默认 SVG 图标

您可以单独或整体使用自己的自定义 SVG 替换 Discourse 的默认 SVG 图标,并在主题或主题组件中覆盖它们。

第 1 步 - 创建 SVG 雪碧图

首先,您需要创建一个 SVG 雪碧图(Spritesheet)。它可以包含从单个额外的自定义 SVG 图标到数百个图标的完整替换集。

雪碧图应保存为 SVG 文件。原则上,您需要将原始 SVG 图标文件中 <svg> 标签的内容嵌套到 <symbol> 标签中,并为其指定一个清晰的标识符。

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <symbol id="my-theme-icon-1">
    <!--
      源 SVG 图标文件中 <svg> 标签内的代码
      这通常是 <svg> 标签之间的所有内容
      (但不包括 SVG 标签本身,它由上面的 <symbol> 替换)
      您可以将任何属性(例如 ViewBox="0 0 0 0")转移到 <symbol> 标签上
      -->
  </symbol>

  <symbol id="my-theme-icon-2">
    <!-- 在此处添加 SVG 代码。根据需要添加更多 <symbol> 块。
      -->
  </symbol>
</svg>
  • 请务必为雪碧图中的每个 symbol 添加自定义 ID。为了便于管理,建议将您的主题名称(例如 my-theme-icon)作为 ID 的前缀。

  • 要使图标颜色像现有图标一样动态变化,请将 fill 设置为 currentColor,而不是硬编码的颜色(如 #333)。

  • 要缩放或正确居中您的图标,请在 <symbol> 标签上使用 viewBox 属性。更多信息请参阅 How to Scale SVG | CSS-Tricks 。

  • 请注意 SVG 内部的样式冲突。例如,SVG 通常会定义内联样式,如 .st0{fill:#FF0000;}。如果您有多个 SVG 使用相同的类,这可能会导致问题(要解决这些问题,请编辑类名使其对每个图标唯一)。

  • 如果您有很多图标,有自动化的方法。 https://www.npmjs.com/package/svg-sprite-generator 是一个简单的命令行工具,用于将 SVG 合并到雪碧图中。

示例 - 单个自定义图标雪碧图

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <symbol id="bat-icon" viewBox="6 6 36 36">
    <path
      fill="currentColor"
      d="M24,18.2c0.7,0,0.9,0.2,0.9,0.2l0.4-1.7c0,0,0.4,1.5,0.4,2.8c0.2,1.1,2.2,0.4,3.9,0C31.4,19.1,32,16,32,16h16c0,0-9.4,3.5-7,10c0,0-14.8-2-17,7l0,0c-2.2-9-17-7-17-7c2.4-6.5-7-10-7-10h16c0,0,0.6,3.1,2.3,3.5c1.7,0.4,3.9,1.1,3.9,0c0.2-1.1,0.4-2.8,0.4-2.8l0.4,1.7C23.1,18.4,23.4,18.2,24,18.2L24,18.2L24,18.2z"
    />
  </symbol>
</svg>

第 2 步 - 将雪碧图添加到您的主题

构建好雪碧图后,您需要将 SVG 文件添加到您的组件/主题中。通过 UI 操作很简单,您也可以将其硬编码到组件/主题中。

:information_source: 一旦上传到任何已安装的组件/主题中,您就可以在整个实例中使用 <symbol> 标签中的 ID 来访问它。

通过 UI

转到主题/组件设置的“上传”部分,添加您的雪碧图文件,并将 SCSS 变量名称设为 icons-sprite:

硬编码到主题 / 组件中

将雪碧图文件添加到主题的 /assets 文件夹中。然后更新根目录中的 assets.json 文件。
对于一个名为 my-icons.svg 的 SVG 雪碧图,您的 about.json 应包含以下内容:

"assets": {
  "icons-sprite": "/assets/my-icons.svg"
}

第 3 步(可选) - 覆盖默认图标

现在雪碧图已设置好,您可以告诉 Discourse 替换图标。这是从 api-initializer 中执行此操作的方法:

// {theme}/javascripts/discourse/api-initializers/init-theme.gjs

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer((api) => {
  api.replaceIcon("bars", "my-theme-icon-bars");
  api.replaceIcon("link", "my-theme-icon-link");
  // 等等。
});

第一个 ID bars 是 Discourse 中的默认图标 ID,第二个是您的替换图标的 ID。查找我们其中一个图标 ID 的最简单方法是在浏览器中检查该图标。

在这里,图标名称遵循 d-icon- 前缀。因此,在这个例子中它是 d-unliked

我们的大多数图标遵循 https://fontawesome.com/ 的图标名称,但有一些例外(这就是为什么在检查器中检查 ID 是最可靠的方法)。您可以在 github 上的这里 的 const REPLACEMENTS 块中看到所有例外。

就这样。现在您可以使用自己的自定义图标来美化 Discourse 了!


本文档受版本控制 - 请在 github 上建议更改。

58 个赞