mirror of
				https://github.com/discourse/discourse.git
				synced 2025-02-25 18:55:32 -06:00 
			
		
		
		
	FEATURE: Allow themes to specify modifiers in their about.json file (#9097)
There are three modifiers: - serialize_topic_excerpts (boolean) - csp_extensions (array of strings) - svg_icons (array of strings) When multiple themes are active, the values will be combined. The combination method varies based on the setting. CSP/SVG arrays will be combined. serialize_topic_excerpts will use `Enumerable#any`.
This commit is contained in:
		
							
								
								
									
										69
									
								
								app/models/theme_modifier_set.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								app/models/theme_modifier_set.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
class ThemeModifierSet < ActiveRecord::Base
 | 
			
		||||
  class ThemeModifierSetError < StandardError; end
 | 
			
		||||
 | 
			
		||||
  belongs_to :theme
 | 
			
		||||
 | 
			
		||||
  MODIFIERS ||= {
 | 
			
		||||
    serialize_topic_excerpts: { combine_mode: :any, type: :boolean },
 | 
			
		||||
    csp_extensions: { combine_mode: :flatten, type: :string_array },
 | 
			
		||||
    svg_icons: { combine_mode: :flatten, type: :string_array },
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  validate :type_validator
 | 
			
		||||
 | 
			
		||||
  def type_validator
 | 
			
		||||
    MODIFIERS.each do |k, config|
 | 
			
		||||
      value = public_send(k)
 | 
			
		||||
      next if value.nil?
 | 
			
		||||
 | 
			
		||||
      case config[:type]
 | 
			
		||||
      when :boolean
 | 
			
		||||
        next if [true, false].include?(value)
 | 
			
		||||
      when :string_array
 | 
			
		||||
        next if value.is_a?(Array) && value.all? { |v| v.is_a?(String) }
 | 
			
		||||
      end
 | 
			
		||||
      errors.add(k, :invalid)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  after_save do
 | 
			
		||||
    if saved_change_to_svg_icons?
 | 
			
		||||
      SvgSprite.expire_cache
 | 
			
		||||
    end
 | 
			
		||||
    if saved_change_to_csp_extensions?
 | 
			
		||||
      CSP::Extension.clear_theme_extensions_cache!
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Given the ids of multiple active themes / theme components, this function
 | 
			
		||||
  # will combine them into a 'resolved' behavior
 | 
			
		||||
  def self.resolve_modifier_for_themes(theme_ids, modifier_name)
 | 
			
		||||
    return nil if !(config = MODIFIERS[modifier_name])
 | 
			
		||||
 | 
			
		||||
    all_values = self.where(theme_id: theme_ids).where.not(modifier_name => nil).pluck(modifier_name)
 | 
			
		||||
    case config[:combine_mode]
 | 
			
		||||
    when :any
 | 
			
		||||
      all_values.any?
 | 
			
		||||
    when :flatten
 | 
			
		||||
      all_values.flatten(1)
 | 
			
		||||
    else
 | 
			
		||||
      raise ThemeModifierSetError "Invalid theme modifier combine_mode"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
# == Schema Information
 | 
			
		||||
#
 | 
			
		||||
# Table name: theme_modifier_sets
 | 
			
		||||
#
 | 
			
		||||
#  id                       :bigint           not null, primary key
 | 
			
		||||
#  theme_id                 :bigint           not null
 | 
			
		||||
#  serialize_topic_excerpts :boolean
 | 
			
		||||
#  csp_extensions           :string           is an Array
 | 
			
		||||
#  svg_icons                :string           is an Array
 | 
			
		||||
#
 | 
			
		||||
# Indexes
 | 
			
		||||
#
 | 
			
		||||
#  index_theme_modifier_sets_on_theme_id  (theme_id) UNIQUE
 | 
			
		||||
#
 | 
			
		||||
		Reference in New Issue
	
	Block a user