您可以单独替换 Discourse 的默认 SVG 图标,或将它们作为一个整体替换为您自己的自定义 SVG,并 在主题或主题组件中 覆盖它们。
步骤 1 - 创建 SVG 精灵图 (Spritesheet)
要开始,您必须创建一个 SVG 精灵图。它可以包含从单个附加的自定义 SVG 图标到数百个完整替换集中的任何内容。
精灵图应保存为 SVG 文件。原则上,您是将原始 SVG 图标文件中的 \u003csvg\u003e 标签内容嵌套到 \u003csymbol\u003e 标签中,并为其指定一个良好的标识符。
<?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 代码在 \u003csvg\u003e 标签内部,来自源 SVG 图标文件
这通常是 \u003csvg\u003e 标签之间的所有内容
(但不包括 SVG 标签本身,它被上面的 \u003csymbol\u003e 替换)
您可以将任何属性(例如 ViewBox="0 0 0 0")转移到 \u003csymbol\u003e 标签上
-->
</symbol>
<symbol id="my-theme-icon-2">
<!-- SVG 代码在这里。根据需要添加更多 \u003csymbol\u003e 块。
-->
</symbol>
</svg>
-
确保在精灵图中的每个 symbol 上添加一个自定义 ID。为了您的方便,最好在 ID 前加上您的主题名称前缀,例如
my-theme-icon。 -
要使图标颜色像现有图标一样动态变化,请将
fill设置为currentColor,而不是硬编码的颜色(如 #333)。 -
要正确缩放或居中您的图标,请在
\u003csymbol\u003e标签上使用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 轻松完成,或者您可以将其硬编码到组件/主题中。
一旦它被上传到任何已安装的组件/主题中,它就可以在您的整个实例中使用
\u003csymbol\u003e标签中的 ID 来访问。
通过 UI
转到主题/组件设置的“上传”部分,并添加您的 sprite 文件,SCSS 变量名称设置为 icons-sprite:
硬编码到主题/组件中
将精灵图文件添加到主题的 /assets 文件夹中。然后更新根文件夹中的 assets.json 文件。
对于名为 my-icons.svg 的 SVG sprite,您的 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 上 建议更改。





