lib/deas/template_source.rb in deas-0.39.2 vs lib/deas/template_source.rb in deas-0.40.0

- old
+ new

@@ -3,44 +3,44 @@ module Deas class TemplateSource - DISALLOWED_ENGINE_EXTS = [ 'rb' ] - - DisallowedEngineExtError = Class.new(ArgumentError) - attr_reader :path, :engines def initialize(path, logger = nil) @path = path.to_s @default_engine_opts = { 'source_path' => @path, 'logger' => logger || Deas::NullLogger.new, 'default_template_source' => self } - @engines = Hash.new{ |h, k| Deas::NullTemplateEngine.new(@default_engine_opts) } + @engines = Hash.new do |hash, ext| + # cache null template exts so we don't repeatedly call this block for + # known null template exts + hash[ext.to_s] = Deas::NullTemplateEngine.new(@default_engine_opts) + end + @engine_exts = [] @ext_lists = Hash.new do |hash, template_name| # An ext list is an array of non-template-name extensions that have engines # configured. The first ext in the list is the most precedent. Its engine # is used to do the initial render from the named template file. Any # further exts are used to compile rendered content from upsteam engines. hash[template_name] = parse_ext_list(template_name) end end def engine(input_ext, engine_class, registered_opts = nil) - if DISALLOWED_ENGINE_EXTS.include?(input_ext) - raise DisallowedEngineExtError, "`#{input_ext}` is disallowed as an"\ - " engine extension." - end + @engine_exts << input_ext.to_s + engine_opts = @default_engine_opts.merge(registered_opts || {}) + engine_opts['ext'] = input_ext.to_s @engines[input_ext.to_s] = engine_class.new(engine_opts) end def engine_for?(ext) - @engines.keys.include?(ext) + @engine_exts.include?(ext.to_s) end def render(template_name, view_handler, locals, &content) [ view_handler.layouts, template_name @@ -60,20 +60,32 @@ end private def compile(name) - ext_list = @ext_lists[name].dup - ext_list.inject(yield @engines[ext_list.shift]) do |content, ext| - @engines[ext].compile(name, content) + @ext_lists[name].drop(1).inject(yield @engines[@ext_lists[name].first]) do |c, e| + @engines[e].compile(name, c) end end def parse_ext_list(template_name) - no_ext_path = "#{File.join(@path, template_name.to_s)}." - path = Dir.glob("#{no_ext_path}*").first || '' - path.sub(no_ext_path, '').split('.').reverse.reject do |ext| - !self.engine_for?(ext) + paths = Dir.glob(File.join(@path, "#{template_name}*")) + if paths.size > 1 + raise ArgumentError, "#{template_name.inspect} matches more than one " \ + "file, consider using a more specific template name" + end + get_ext_list(paths.first.to_s) + end + + def get_ext_list(path) + # get the base name of the path (file name plus extensions). Split on the + # periods and drop the first value (the file name). reverse the list b/c + # we process exts right-to-left. reject any unnecessary exts. + File.basename(path).split('.').drop(1).reverse.reject.each_with_index do |e, i| + # keep the first ext (for initial render from source) and any registered + # exts. remove any non-first non-registered exts so you don't have the + # overhead of running through the null engine for each. + i != 0 && !self.engine_for?(e) end end end