FEATURE: support custom icons in themes (#7155)

* First take

* Add support for sprites in themes

Automatically register any custom icons added via themes or plugins

* Fix theme sprite caching

* Simplify test

* Update lib/svg_sprite/svg_sprite.rb

Co-Authored-By: pmusaraj <pmusaraj@gmail.com>

* Fix /svg-sprite/search request
This commit is contained in:
Penar Musaraj
2019-03-15 02:16:15 -04:00
committed by Sam
parent 32db3ac228
commit d6d4a5ba4a
7 changed files with 94 additions and 12 deletions

View File

@@ -189,8 +189,28 @@ module SvgSprite
FA_ICON_MAP = { 'far fa-' => 'far-', 'fab fa-' => 'fab-', 'fas fa-' => '', 'fa-' => '' }
SVG_SPRITE_PATHS = Dir.glob(["#{Rails.root}/vendor/assets/svg-icons/**/*.svg",
"#{Rails.root}/plugins/*/svg-icons/*.svg"])
CORE_SVG_SPRITES = Dir.glob("#{Rails.root}/vendor/assets/svg-icons/**/*.svg")
THEME_SPRITE_VAR_NAME = "icons-sprite"
def self.custom_svg_sprites(theme_ids = [])
custom_sprite_paths = Dir.glob("#{Rails.root}/plugins/*/svg-icons/*.svg")
ThemeField.where(type_id: ThemeField.types[:theme_upload_var], name: THEME_SPRITE_VAR_NAME, theme_id: Theme.transform_ids(theme_ids))
.pluck(:upload_id).each do |upload_id|
upload = Upload.find(upload_id)
original_path = Discourse.store.path_for(upload)
if original_path.blank?
external_copy = Discourse.store.download(upload) rescue nil
original_path = external_copy.try(:path)
end
custom_sprite_paths << Discourse.store.path_for(upload) if original_path.present?
end
custom_sprite_paths
end
def self.all_icons(theme_ids = [])
get_set_cache("icons_#{Theme.transform_ids(theme_ids).join(',')}") do
@@ -200,6 +220,7 @@ module SvgSprite
.merge(badge_icons)
.merge(group_icons)
.merge(theme_icons(theme_ids))
.merge(custom_icons(theme_ids))
.delete_if { |i| i.blank? || i.include?("/") }
.map! { |i| process(i.dup) }
.merge(SVG_ICONS)
@@ -221,11 +242,13 @@ module SvgSprite
cache&.clear
end
def self.sprite_sources(theme_ids)
CORE_SVG_SPRITES | custom_svg_sprites(theme_ids)
end
def self.bundle(theme_ids = [])
icons = all_icons(theme_ids)
doc = File.open("#{Rails.root}/vendor/assets/svg-icons/fontawesome/solid.svg") { |f| Nokogiri::XML(f) }
svg_subset = """<!--
Discourse SVG subset of Font Awesome Free by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
@@ -233,7 +256,7 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
<svg xmlns='http://www.w3.org/2000/svg' style='display: none;'>
""".dup
SVG_SPRITE_PATHS.each do |fname|
sprite_sources(theme_ids).each do |fname|
svg_file = Nokogiri::XML(File.open(fname)) do |config|
config.options = Nokogiri::XML::ParseOptions::NOBLANKS
end
@@ -256,7 +279,7 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
def self.search(searched_icon)
searched_icon = process(searched_icon.dup)
SVG_SPRITE_PATHS.each do |fname|
sprite_sources([SiteSetting.default_theme_id]).each do |fname|
svg_file = Nokogiri::XML(File.open(fname))
svg_filename = "#{File.basename(fname, ".svg")}"
@@ -274,6 +297,10 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
false
end
def self.theme_sprite_variable_name
THEME_SPRITE_VAR_NAME
end
def self.prepare_symbol(symbol, svg_filename)
icon_id = symbol.attr('id')
@@ -331,6 +358,19 @@ License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL
theme_icon_settings
end
def self.custom_icons(theme_ids)
# Automatically register icons in sprites added via themes or plugins
icons = []
custom_svg_sprites(theme_ids).each do |fname|
svg_file = Nokogiri::XML(File.open(fname))
svg_file.css('symbol').each do |sym|
icons << sym.attributes['id'].value
end
end
icons
end
def self.fa4_shim_file
"#{Rails.root}/lib/svg_sprite/fa4-renames.json"
end