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
73
74
75
76
77
78
79
80
81
82
# 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

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



207
208
209
# File 'lib/deface/override.rb', line 207

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

.allObject



203
204
205
# File 'lib/deface/override.rb', line 203

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.



197
198
199
200
201
# 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

Instance Method Details

#actionObject



133
134
135
# File 'lib/deface/override.rb', line 133

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

#attributesObject

returns attributes hash for attribute related actions



173
174
175
# File 'lib/deface/override.rb', line 173

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

#digestObject

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



187
188
189
190
# 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

#disabled?Boolean

Returns:

  • (Boolean)


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

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

#end_selectorObject



166
167
168
169
# File 'lib/deface/override.rb', line 166

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

#nameObject



88
89
90
# File 'lib/deface/override.rb', line 88

def name
  @args[:name]
end

#railtie_classObject



92
93
94
# File 'lib/deface/override.rb', line 92

def railtie_class
  @args[:railtie_class]
end

#safe_source_elementObject



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

def safe_source_element
  return unless source_argument
  source_element
end

#selectorObject



84
85
86
# File 'lib/deface/override.rb', line 84

def selector
  @args[self.action]
end

#sequenceObject



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
122
123
124
125
126
127
128
129
130
131
# 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

#sourceObject

Returns the markup to be inserted / used

Raises:



139
140
141
142
143
144
145
# 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

#source_argumentObject

Returns a :symbol for the source argument present



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

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

#source_elementObject



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

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

#touchObject

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



180
181
182
# File 'lib/deface/override.rb', line 180

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