module Temple::Mixins::EngineDSL
def after(name, *args, &block)
def after(name, *args, &block) name = Class === name ? name.name.to_sym : name raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name e = element(args, block) found, i = false, 0 while i < chain.size if chain[i].first == name found = true i += 1 chain.insert(i, e) end i += 1 end raise "#{name} not found" unless found chain_modified! end
def append(*args, &block)
def append(*args, &block) chain << element(args, block) chain_modified! end
def before(name, *args, &block)
def before(name, *args, &block) name = Class === name ? name.name.to_sym : name raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name e = element(args, block) found, i = false, 0 while i < chain.size if chain[i].first == name found = true chain.insert(i, e) i += 2 else i += 1 end end raise "#{name} not found" unless found chain_modified! end
def chain_modified!
def chain_modified! end
def element(args, block)
def element(args, block) name = args.shift if Class === name filter = name name = filter.name.to_sym end raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name if block raise(ArgumentError, 'Class and block argument are not allowed at the same time') if filter filter = block end filter ||= args.shift case filter when Proc # Proc or block argument # The proc is converted to a method of the engine class. # The proc can then access the option hash of the engine. raise(ArgumentError, 'Too many arguments') unless args.empty? raise(ArgumentError, 'Proc or blocks must have arity 1') unless filter.arity == 1 method_name = "FILTER #{name}" if Class === self define_method(method_name, &filter) [name, instance_method(method_name)] else (class << self; self; end).class_eval { define_method(method_name, &filter) } [name, method(method_name)] end when Class # Class argument (e.g Filter class) # The options are passed to the classes constructor. local_options = Hash === args.last ? args.pop : nil raise(ArgumentError, 'Only symbols allowed in option filter') unless args.all? {|o| Symbol === o } [name, filter, args, local_options] else # Other callable argument (e.g. Object of class which implements #call or Method) # The callable has no access to the option hash of the engine. raise(ArgumentError, 'Class or callable argument is required') unless filter.respond_to?(:call) [name, filter] end end
def filter(name, *options, &block)
def filter(name, *options, &block) use(name, Temple::Filters.const_get(name), *options, &block) end
def generator(name, *options, &block)
def generator(name, *options, &block) use(name, Temple::Generators.const_get(name), *options, &block) end
def prepend(*args, &block)
def prepend(*args, &block) chain.unshift(element(args, block)) chain_modified! end
def remove(name)
def remove(name) found = false chain.reject! do |i| equal = i.first == name found = true if equal equal end raise "#{name} not found" unless found chain_modified! end
def replace(name, *args, &block)
def replace(name, *args, &block) name = Class === name ? name.name.to_sym : name raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name e = element(args, block) found = false chain.each_with_index do |c, i| if c.first == name found = true chain[i] = e end end raise "#{name} not found" unless found chain_modified! end