Redmine 6+ перешел на использование SVG-спрайтов для иконок вместо традиционных PNG. Это улучшает производительность, уменьшает количество HTTP-запросов и упрощает управление иконками.
Данный документ описывает, как правильно подключить SVG-иконки в новый плагин, учитывая официальные рекомендации Redmine.
- 1. Использование стандартных иконок Redmine
- 2. Подключение кастомных иконок в плагин
- 3. CSS-правила для совместимости с PNG-иконками
- 4. Дополнительные rake-задачи для работы с иконками
- 5. Поддержка старых версий Redmine
- 6. Возможные ошибки и их решения
- Итог
- Примечания
1. Использование стандартных иконок Redmine
Перед добавлением кастомных иконок в плагин рекомендуется использовать встроенные SVG-иконки Redmine.
Это делается с помощью метода sprite_icon:
<%= sprite_icon('pencil', l(:button_edit)) %>
<%= sprite_icon('plus', l(:button_add)) %>
<%= sprite_icon('trash', l(:button_delete)) %>
<%= sprite_icon('specific_plugin_icon', l(:button_delete)), plugin: :redmine_plugin_name %>
Этот метод автоматически использует icons.svg, встроенный в Redmine.
Важно! Некоторые иконки, такие как add, delete, copy, edit, уже существуют в общем спрайте Redmine. Их необходимо использовать без указания плагина, чтобы избежать дублирования:
<%= sprite_icon('add', l(:button_add)) %>
<%= sprite_icon('delete', l(:button_delete)) %>
<%= sprite_icon('copy', l(:button_copy)) %>
Если указать параметр plugin, Redmine будет искать эти иконки в спрайте плагина, но они уже есть в общем наборе Redmine, и их повторное создание не требуется.
2. Подключение кастомных иконок в плагин
Шаг 1: Создание config/icon_source.yml
Чтобы использовать дополнительные иконки, необходимо создать config/icon_source.yml в папке плагина.
Этот файл позволяет скачивать SVG-иконки из Tabler Icons и автоматически включать их в спрайт.
Пример config/icon_source.yml:
# This file is used by icons rake task to download SVG icons from Tabler
# Keys description:
# - name: destination icon name (используется в sprite_icon)
# svg: source icon name from Tabler Icons
# style: outline (default) or filled
- name: custom-icon
svg: star
- name: reload
svg: refresh
- name — название иконки, которое будет использоваться в sprite_icon.
- svg — оригинальное название иконки в Tabler Icons.
- style — необязательный параметр (outline или filled).
Шаг 2: Генерация icons.svg для плагина
После настройки config/icon_source.yml необходимо выполнить команду:
rake icons:plugin:generate NAME=<redmine_plugin_name>
Эта команда:
- Загружает нужные иконки из Tabler Icons.
- Создает
icons.svgв папкеpublic/plugin_assets/./images/ - Генерирует SVG-спрайт, который можно использовать в шаблонах.
После выполнения команды можно проверить содержимое файла icons.svg и при необходимости внести правки вручную.
Шаг 3: Использование кастомных иконок в шаблонах
После генерации icons.svg можно использовать иконки в шаблонах плагина:
<%= sprite_icon('custom-icon', plugin: :<redmine_plugin_name>) %>
<%= sprite_icon('reload', plugin: :<redmine_plugin_name>) %>
Важно! Использовать plugin необходимо только для кастомных иконок, которых нет в общем наборе Redmine.
3. CSS-правила для совместимости с PNG-иконками
Для обратной совместимости с CSS-классами, которые использовали PNG-файлы, необходимо обновить CSS.
Используем :not(:has(svg)), чтобы подставлять PNG только там, где нет SVG.
Пример app/assets/stylesheets/:
.icon-edit:not(:has(svg)) { background-image: url(../images/pencil.png); }
.icon-add:not(:has(svg)) { background-image: url(../images/circle-plus.png); }
.icon-copy:not(:has(svg)) { background-image: url(../images/copy.png); }
.icon-del:not(:has(svg)) { background-image: url(../images/trash.png); }
Если браузер не поддерживает :has(), используйте JavaScript для удаления background-image у элементов с <svg>.
document.querySelectorAll('.icon').forEach(icon => {
if (icon.querySelector('svg')) {
icon.style.backgroundImage = 'none';
}
});
4. Дополнительные rake-задачи для работы с иконками
| Команда | Описание |
|---|---|
rake icons:download |
Загружает стандартные иконки Redmine |
rake icons:generate |
Загружает иконки и создаёт SVG-спрайт |
rake icons:plugin:download |
Загружает SVG-иконки для плагина |
rake icons:plugin:generate |
Загружает иконки и создаёт спрайт для плагина |
rake icons:plugin:sprite |
Генерирует только спрайт для плагина |
rake icons:sprite |
Генерирует общий SVG-спрайт |
Используйте rake icons:plugin:generate NAME=, чтобы обновить спрайт.
5. Поддержка старых версий Redmine
Для обратной совместимости с Redmine 5 и ниже, где sprite_icon может отсутствовать, используйте патч совместимости.
Добавление поддержки в init.rb
require 'redmineup/patches/compatibility_patch'
Этот патч автоматически адаптирует работу с иконками на старых версиях Redmine.
6. Возможные ошибки и их решения
| Ошибка | Решение |
|---|---|
| Иконка не отображается | Убедитесь, что указан plugin: : в sprite_icon. |
Иконка не добавилась в icons.svg |
Проверьте, что config/icon_source.yml содержит правильные значения и повторно запустите rake icons:plugin:generate. |
Изменения в icons.svg не применяются |
Выполните rake assets:precompile, чтобы пересобрать файлы. |
| Отображаются старые PNG-иконки | Добавьте :not(:has(svg)) в CSS, чтобы отключить background-image. |
Итог
- Использовать стандартные иконки Redmine без
plugin, чтобы не дублировать их. - Создать
config/icon_source.ymlи указать список кастомных иконок. - Сгенерировать
icons.svgс помощьюrake icons:plugin:generate. - Использовать
sprite_icon('custom-icon', plugin: :только для новых иконок.) - Добавить CSS-фильтр
:not(:has(svg))для отключения старых иконок. - Пересобрать ассеты (
rake assets:precompile). - Для обратной совместимости подключить
compatibility_patch.
Соблюдение этих рекомендаций обеспечит корректное отображение SVG-иконок в плагине и совместимость с Redmine 6+.
Примечания
- Осталась проблема с иконками на странице активности. Проблема связана с тем, что метод activity_event_type_icon не учитывает иконки из ресурсов плагинов, даже после исправлений в версии 6.0.2.