Class: Deface::Override

Inherits:
Object
  • Object
show all
Extended by:
Applicator::ClassMethods, Search::ClassMethods
Includes:
Applicator, OriginalValidator
Defined in:
lib/deface/override.rb

Constant Summary collapse

@@_early =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Applicator::ClassMethods

apply

Methods included from Search::ClassMethods

find, find_using

Methods included from Applicator

#compatible_with_end_selector?, #create_action_command, #execute_action, #execute_action_on_range, #matcher

Methods included from OriginalValidator

#original_source, #validate_original

Constructor Details

#initialize(args, &content) ⇒ Override

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!

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 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

  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

Instance Attribute Details

#argsObject

Returns the value of attribute args.



9
10
11
# File 'lib/deface/override.rb', line 9

def args
  @args
end

#failureObject

Returns the value of attribute failure.



9
10
11
# File 'lib/deface/override.rb', line 9

def failure
  @failure
end

#parsed_documentObject

Returns the value of attribute parsed_document.



9
10
11
# File 'lib/deface/override.rb', line 9

def parsed_document
  @parsed_document
end

Class Method Details

.actionsObject



196
197
198
# File 'lib/deface/override.rb', line 196

def self.actions
  Rails.application.config.deface.actions.map &:to_sym
end

.allObject



192
193
194
# File 'lib/deface/override.rb', line 192

def self.all
  Rails.application.config.deface.overrides.all
end

.digest(details) ⇒ Object

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.



186
187
188
189
190
# File 'lib/deface/override.rb', line 186

def self.digest(details)
  overrides = self.find(details)

  Digest::MD5.new.update(overrides.inject('') { |digest, override| digest << override.digest }).hexdigest
end

Instance Method Details

#actionObject



123
124
125
# File 'lib/deface/override.rb', line 123

def action
  (self.class.actions & @args.keys).first
end

#attributesObject

returns attributes hash for attribute related actions



163
164
165
# File 'lib/deface/override.rb', line 163

def attributes
  @args[:attributes] || []
end

#digestObject

Creates MD5 hash of args sorted keys and values used to determine if an override has changed



177
178
179
# File 'lib/deface/override.rb', line 177

def digest
  Digest::MD5.new.update(@args.keys.map(&:to_s).sort.concat(@args.values.map(&:to_s).sort).join).hexdigest
end

#disabled?Boolean

Returns:

  • (Boolean)


152
153
154
# File 'lib/deface/override.rb', line 152

def disabled?
  @args.key?(:disabled) ? @args[:disabled] : false
end

#end_selectorObject



156
157
158
159
# File 'lib/deface/override.rb', line 156

def end_selector
  return nil if @args[:closing_selector].blank?
  @args[:closing_selector]
end

#nameObject



78
79
80
# File 'lib/deface/override.rb', line 78

def name
  @args[:name]
end

#railtie_classObject



82
83
84
# File 'lib/deface/override.rb', line 82

def railtie_class
  @args[:railtie_class]
end

#safe_source_elementObject



147
148
149
150
# File 'lib/deface/override.rb', line 147

def safe_source_element
  return unless source_argument
  source_element
end

#selectorObject



74
75
76
# File 'lib/deface/override.rb', line 74

def selector
  @args[self.action]
end

#sequenceObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/deface/override.rb', line 86

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

#sourceObject

Returns the markup to be inserted / used

Raises:



129
130
131
132
133
134
135
# File 'lib/deface/override.rb', line 129

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

#source_argumentObject

Returns a :symbol for the source argument present



139
140
141
# File 'lib/deface/override.rb', line 139

def source_argument
  Deface::DEFAULT_SOURCES.detect { |source| @args.key? source.to_sym }.try :to_sym
end

#source_elementObject



143
144
145
# File 'lib/deface/override.rb', line 143

def source_element
  Deface::Parser.convert(source.clone)
end

#touchObject

Alters digest of override to force view method recompilation (when source template/partial changes)



170
171
172
# File 'lib/deface/override.rb', line 170

def touch
  @args[:updated_at] = Time.zone.now.to_f
end