Вы можете заменить стандартные SVG-иконки Discourse индивидуально или целиком на собственные кастомные SVG и переопределить их внутри темы или компонента темы.
Шаг 1 — Создание SVG-спрайта
Для начала вам необходимо создать SVG-спрайт. Он может содержать как одну дополнительную кастомную 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>
-
Убедитесь, что каждому символу в спрайте присвоен уникальный ID. Вероятно, для вашего душевного равновесия будет полезно использовать префикс с названием вашей темы, например
my-theme-icon. -
Чтобы цвет иконки был динамическим, как у существующих иконок, установите значение
fillвcurrentColor, а не в жёстко заданный цвет (например, #333). -
Для масштабирования или правильного центрирования вашей иконки используйте атрибут
viewBoxв теге<symbol>. Дополнительную информацию можно найти здесь: 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-файл в ваш компонент/тему. Это легко сделать через интерфейс, или вы можете захардкодить его в компонент/тему.
Как только файл будет загружен в любой установленный компонент/тему, он будет доступен во всей вашей инстанции с использованием ID из тега
<symbol>.
Через интерфейс
Перейдите в раздел Uploads (Загрузки) в настройках темы/компонента и добавьте ваш файл спрайта с именем SCSS-переменной icons-sprite:
Захардкодить в Тему / Компонент
Добавьте файл спрайта в папку /assets темы. Затем обновите файл assets.json в корневой папке.
Для SVG-спрайта с названием my-icons.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, — это стандартный ID иконки в Discourse, а второй — ID вашей заменяющей иконки. Самый простой способ найти ID одной из наших иконок — исследовать иконку в вашем браузере.
Здесь имя иконки следует за префиксом d-icon-. Таким образом, в этом примере это d-unliked.
Большинство наших иконок следуют именам иконок с https://fontawesome.com/, но есть исключения (именно поэтому проверка ID в инспекторе является наиболее надежным методом). Все исключения можно увидеть в блоке const REPLACEMENTS здесь на github.
Всё. Теперь вы можете стилизовать Discourse с помощью собственных кастомных иконок!
Этот документ находится под контролем версий — предложите изменения на github.








