class Deface::Override
Attributes
Public Class Methods
# File lib/deface/override.rb, line 207 def self.actions Rails.application.config.deface.actions.map &:to_sym end
# File lib/deface/override.rb, line 203 def self.all Rails.application.config.deface.overrides.all end
Creates MD5 of all overrides that apply to a particular virtual_path, used in CompiledTemplates method name so we can support re-compiling of compiled method when overrides change. Only of use in production mode.
# File lib/deface/override.rb, line 197 def self.digest(details) overrides = self.find(details) to_hash = overrides.inject('') { |digest, override| digest << override.digest } Deface::Digest.hexdigest(to_hash) end
Initializes new override, you must supply only one Target, Action & Source parameter for each override (and any number of Optional parameters).
See READme for more!
# File lib/deface/override.rb, line 17 def initialize(args, &content) if Rails.application.try(:config).try(:deface).try(:enabled) unless Rails.application.config.deface.try(:overrides) @@_early << args warn "[WARNING] You no longer need to manually require overrides, remove require for '#{args[:name]}'." return end else warn "[WARNING] You no longer need to manually require overrides, remove require for '#{args[:name]}'." return end # If no name was specified, use the filename and line number of the caller # Including the line number ensure unique names if multiple overrides # are defined in the same file unless args.key? :name parts = caller[0].split(':') file_name = File.basename(parts[0], '.rb') line_number = parts[1] args[:name] = "#{file_name}_#{line_number}" end raise(ArgumentError, ":name must be defined") unless args.key? :name raise(ArgumentError, ":virtual_path must be defined") if args[:virtual_path].blank? args[:text] = content.call if block_given? args[:name] = "#{current_railtie.underscore}_#{args[:name]}" if Rails.application.try(:config).try(:deface).try(:namespaced) || args.delete(:namespaced) virtual_key = args[:virtual_path].to_sym name_key = args[:name].to_s.parameterize self.class.all[virtual_key] ||= {} if self.class.all[virtual_key].has_key? name_key #updating exisiting override @args = self.class.all[virtual_key][name_key].args #check if the action is being redefined, and reject old action if (self.class.actions & args.keys).present? @args.reject!{|key, value| (self.class.actions & @args.keys).include? key } end #check if the source is being redefined, and reject old action if (Deface::DEFAULT_SOURCES.map(&:to_sym) & args.keys).present? @args.reject!{|key, value| (Deface::DEFAULT_SOURCES.map(&:to_sym) & @args.keys).include? key } end @args.merge!(args) else #initializing new override @args = args raise(ArgumentError, ":action is invalid") if self.action.nil? end #set loaded time (if not already present) for hash invalidation @args[:updated_at] ||= Time.zone.now.to_f @args[:railtie_class] = self.class.current_railtie self.class.all[virtual_key][name_key] = self expire_compiled_template self end
Public Instance Methods
# File lib/deface/override.rb, line 133 def action (self.class.actions & @args.keys).first end
returns attributes hash for attribute related actions
# File lib/deface/override.rb, line 173 def attributes @args[:attributes] || [] end
Creates MD5 hash of args sorted keys and values used to determine if an override has changed
# File lib/deface/override.rb, line 187 def digest to_hash = @args.keys.map(&:to_s).sort.concat(@args.values.map(&:to_s).sort).join Deface::Digest.hexdigest(to_hash) end
# File lib/deface/override.rb, line 162 def disabled? @args.key?(:disabled) ? @args[:disabled] : false end
# File lib/deface/override.rb, line 166 def end_selector return nil if @args[:closing_selector].blank? @args[:closing_selector] end
# File lib/deface/override.rb, line 88 def name @args[:name] end
# File lib/deface/override.rb, line 92 def railtie_class @args[:railtie_class] end
# File lib/deface/override.rb, line 157 def safe_source_element return unless source_argument source_element end
# File lib/deface/override.rb, line 84 def selector @args[self.action] end
# File lib/deface/override.rb, line 96 def sequence return 100 unless @args.key?(:sequence) if @args[:sequence].is_a? Hash key = @args[:virtual_path].to_sym if @args[:sequence].key? :before ref_name = @args[:sequence][:before] if self.class.all[key].key? ref_name.to_s return self.class.all[key][ref_name.to_s].sequence - 1 else return 100 end elsif @args[:sequence].key? :after ref_name = @args[:sequence][:after] if self.class.all[key].key? ref_name.to_s return self.class.all[key][ref_name.to_s].sequence + 1 else return 100 end else #should never happen.. tut tut! return 100 end else return @args[:sequence].to_i end rescue SystemStackError if defined?(Rails) Rails.logger.error "\e[1;32mDeface: [WARNING]\e[0m Circular sequence dependency includes override named: '#{self.name}' on '#{@args[:virtual_path]}'." end return 100 end
Returns the markup to be inserted / used
# File lib/deface/override.rb, line 139 def source sources = Rails.application.config.deface.sources source = sources.find { |source| source.to_sym == source_argument } raise(DefaceError, "Source #{source} not found.") unless source source.execute(self) || '' end
Returns a :symbol for the source argument present
# File lib/deface/override.rb, line 149 def source_argument Deface::DEFAULT_SOURCES.detect { |source| @args.key? source.to_sym }.try :to_sym end
# File lib/deface/override.rb, line 153 def source_element Deface::Parser.convert(source.clone) end
Alters digest of override to force view method recompilation (when source template/partial changes)
# File lib/deface/override.rb, line 180 def touch @args[:updated_at] = Time.zone.now.to_f end
Private Instance Methods
check if method is compiled for the current virtual path
# File lib/deface/override.rb, line 216 def expire_compiled_template if compiled_method_name = ActionView::CompiledTemplates.instance_methods.detect { |name| name =~ /#{args[:virtual_path].gsub(/[^a-z_]/, '_')}/ } #if the compiled method does not contain the current deface digest #then remove the old method - this will allow the template to be #recompiled the next time it is rendered (showing the latest changes) unless compiled_method_name =~ /\A_#{self.class.digest(:virtual_path => @args[:virtual_path])}_/ ActionView::CompiledTemplates.send :remove_method, compiled_method_name end end end