require 'mustache' # extendending implementation of module Sbuilder class Template < Mustache include Sbuilder::Utils::MyLogger # mix logger PROGNAME = "template" # progname for logger # ------------------------------------------------------------------ # Attributes # instance attr_writer :partials # f: partial-name --> template string attr_reader :reader # Sbuilder::TemplateReader implementing # 'get_template', 'get_template_filepath' extend Forwardable # for easy delegation def_delegators :reader,:get_template, :get_template_filepath, :configSetup, :template_read # ------------------------------------------------------------------ # Constructor def initialize( reader, options={} ) @logger = getLogger( PROGNAME, options ) @logger.info( "#{__method__} created" ) @logger.debug( "#{__method__}, options='#{options}" ) # init partial cache @partials = {} # inject reader #@reader = Sbuilder::TemplateReader.new( options ) @reader = reader end # ------------------------------------------------------------------ # Services def to_str( template_name, data ) @logger.info( "#{__method__}: template_name=#{template_name}" ) @logger.debug( "#{__method__}: template_name=#{template_name}" ) if @logger.debug? # @logger.debug( "#{__method__}: nodes=#{data.nodes}" ) # data = add_dynamic_load( data ) @data = data template = get_template( template_name ) # render( template, @data ) render( template, @data ) end def render_str( template, data ) render( template, data ) end # ------------------------------------------------------------------ # Integrate with mustache # method used by mustache framework - delegate to 'get_partial' def partial(name) @logger.debug( "#{__method__} name=#{name}" ) # return resolve_partial_direct(name[2..-1]) if name[0..1] == '!!' get_partial( resolve_partial_name(name) ) end # # # # @param path_template [String] mustache template string to intepret for path # # # # @return [String] content of file pointed by rendering 'path_template' # def resolve_partial_direct( path_template ) # # change mustache delimerters to allow rendering # # templ = "{{=%% %%=}}#{path_template}<%={{ }}=%>" # puts path_template # templ = path_template # path = render( templ, @data ) # template_read( path ) # end # lookup def resolve_partial_name( name ) return name unless name[0..0] == '!' # remove !, split, and use injected traves to access data ret = @data.traverse( *(name[1..-1].split( "." )) ) if ret.nil? raise <<-EOS Could not resolve #{name} in template data #{@data.to_yaml} EOS end @logger.info( "#{__method__} name=#{name} --> #{ret}" ) ret end # ------------------------------------------------------------------ # Cache partials once resoved # cache @partials - for easier extension def get_partial( name ) @logger.debug( "#{__method__} name=#{name}" ) return @partials[name] if @partials[name] @logger.info( "#{__method__} read partial_file=#{name}" ) @partials[name] = get_template( name ) return @partials[name] # partial_file = get_template_filepath( name ) # @logger.info( "#{__method__} read partial_file=#{partial_file}" ) # @partials[name] = File.read( partial_file ) # @partials[name] end end # class end # module