class Malt::Machine
The Machine
class encapsulates Malt's main methods along with configuratable settings to control which engines and formats are used for rendering.
Constants
- MARKUP
List of markup types. These are formats that just allow markup transformations and do not provide for data injection.
- TEMPLATE
List of template types. These are template formats that provide data injection.
- TEMPLATE_SAFE
Template
types that prevent arbitrary Ruby code execution.
Public Class Methods
# File lib/malt/machine.rb, line 27 def initialize(config={}) if priority = config[:priority] priority = priority.map{ |e| e.to_sym } else priority = [] end if types = config[:types] || config[:type] formats = {} engines = {} types.each do |type| k = ext_to_type(type) formats[k] = Malt::Format.registry[k] engines[k] = Malt::Engine.registry[k] end else formats = Malt::Format.registry #.dup engines = Malt::Engine.registry #.dup end @formats = formats @engines = engines @priority = priority end
Public Instance Methods
# File lib/malt/machine.rb, line 74 def engine?(ext) type = ext_to_type(ext) engines.key?(type) ##ext = ext.to_s ##type = ext.sub(/^\./, '').strip ##return false if type.empty? ###@registry.key?(ext.to_sym) ###Engine.registry[type.to_sym] ##Engine.registry.key?(type.to_sym) end
# File lib/malt/machine.rb, line 56 def engines @engines end
# File lib/malt/machine.rb, line 92 def file(file, options={}) type = options[:type] || options[:format] || File.extname(file) type = ext_to_type(type) malt_class = formats[type] raise "unknown type -- #{type}" unless malt_class malt_class.new(options.merge(:file=>file,:type=>type)) end
# File lib/malt/machine.rb, line 86 def format?(ext) type = ext_to_type(ext) formats.key?(type) end
# File lib/malt/machine.rb, line 51 def formats @formats end
Engine
priorities.
Returns an Array of symbolic engine names.
# File lib/malt/machine.rb, line 63 def priority(type=nil) if type type = type.to_s.downcase.to_sym @priority.unshift(type) @priority.uniq! # assuming first are kept end @priority end
Render template directly.
parameters - File name of template. Used to read text. parameters - Text of template document. parameters - File type/extension used to look up engine. parameters - If not a supported type return text rather than raise an error. parameters - Force the use of a this specific engine. parameters - Format
to convert to (usual default is `html`).
# File lib/malt/machine.rb, line 133 def render(parameters={}, &content) parameters = normalize_parameters(parameters) if parameters[:multi] multi_render(parameters, &content) else single_render(parameters, &content) end end
# File lib/malt/machine.rb, line 101 def text(text, options={}) if file = options[:file] ext = File.extname(file) ext = nil if ext.empty? end type = options[:type] || options[:format] || ext type = ext_to_type(type) malt_class = formats[type] || Format::Text # :pass ? #raise "unkown type -- #{type}" unless malt_class malt_class.new(options.merge(:text=>text,:file=>file,:type=>type)) end
Private Instance Methods
# File lib/malt/machine.rb, line 214 def engine(type, engine=nil) type = ext_to_type(type) #engine = engine || Malt.config.engine[type] # FIXME case engine when Class #raise unless Engine.registry[type].include?(engine) engine when String, Symbol match = engine.to_s.downcase.to_sym #Engine.registry[type].find{ |e| e.basename.downcase == match } #engines[type].find{ |e| e.basename.downcase == match } engines[type].find{ |e| match == e.type } else if engines[type] #Engine.registry[type].first types = engines[type] if prior = types.find{ |e| priority.include?(e.type) } return prior end if default = Engine.defaults[type] return default #if engine?(default.type) end types.first else nil end end end
Normal file extension to a symbol type reference.
# File lib/malt/machine.rb, line 268 def ext_to_type(ext) ext = ext.to_s.downcase return nil if ext.empty? if ext[0,1] == '.' ext[1..-1].to_sym else ext.to_sym end end
TODO: Handle File objects and URLs.
# File lib/malt/machine.rb, line 263 def file_read(file) File.read(file) end
# File lib/malt/machine.rb, line 245 def file_type(file, type=nil) ext = type || File.extname(file) ext = ext.to_s.downcase if ext.empty? nil elsif ext[0,1] == '.' ext[1..-1].to_sym else ext.to_sym end end
# File lib/malt/machine.rb, line 166 def multi_render(parameters={}, &content) type = parameters[:type] #file = parameters[:file] text = parameters[:text] if type = parameters[:type] types = [type].flatten else types = file.split('.')[1..-1] end types.reverse_each do |t| parameters[:type] = t parameters[:text] = single_render(parameters, &content) end parameters[:text] end
Normalize parameters.
# File lib/malt/machine.rb, line 146 def normalize_parameters(parameters) params = parameters.rekey if data = params.delete(:data) scope, locals = split_data(data) params[:scope] ||= scope params[:locals] ||= locals end file = params[:file] text = params[:text] unless text params[:text] = file_read(file) end params end
# File lib/malt/machine.rb, line 186 def single_render(parameters={}, &content) type = parameters[:type] file = parameters[:file] text = parameters[:text] engine = parameters[:engine] type = file_type(file, type) #text = file_read(file) unless text engine_class = engine(type, engine) if engine_class parameters[:type] = type parameters[:text] = text engine = engine_class.new engine.render(parameters, &content) else if parameters[:pass] text else raise NoEngineError, "no engine to handle `#{type}' format" end end end
Unlike #scope_and_locals
, this method returns nil
for missing scope or locals.
# File lib/malt/machine.rb, line 281 def split_data(data) scope, locals = *[data].flatten if scope.respond_to?(:to_hash) locals ||= {} locals = locals.merge(scope.to_hash) scope = nil end return scope, locals end