The default template class for Arrow.
(Not documented)
Create an attr_accessor method for the specified sym, but one which will look for instance variables with any leading underbars removed.
# File lib/arrow/template.rb, line 264
264: def self::attr_underbarred_accessor( sym )
265: ivarname = '@' + sym.to_s.gsub( /^_+/, '' )
266: define_method( sym ) {
267: self.instance_variable_get( ivarname )
268: }
269: define_method( "#{sym}=" ) {|arg|
270: self.instance_variable_set( ivarname, arg )
271: }
272: end
Create an attr_reader method for the specified sym, but one which will look for instance variables with any leading underbars removed.
# File lib/arrow/template.rb, line 254
254: def self::attr_underbarred_reader( sym )
255: ivarname = '@' + sym.to_s.gsub( /^_+/, '' )
256: define_method( sym ) {
257: self.instance_variable_get( ivarname )
258: }
259: end
Find the specified file in the given path (or the Template class‘s #load_path if not specified).
# File lib/arrow/template.rb, line 237
237: def self::find_file( file, path=[] )
238: raise TemplateError, "Filename #{file} is tainted." if
239: file.tainted?
240:
241: filename = path.
242: collect {|dir| File.expand_path(file, dir).untaint }.
243: find {|fn| File.file?(fn) }
244: raise Arrow::TemplateError,
245: "Template '%s' not found. Search path was %p" %
246: [ file, path ] unless filename
247:
248: return filename
249: end
Load a template from a file.
# File lib/arrow/template.rb, line 209
209: def self::load( name, path=[] )
210:
211: # Find the file on either the specified or default path
212: path = self.load_path if path.empty?
213: Arrow::Logger[self].debug "Searching for template '%s' in %d directories" %
214: [ name, path.size ]
215: filename = self.find_file( name, path )
216: Arrow::Logger[self].debug "Found '%s'" % [ filename ]
217:
218: # Read the template source
219: source = File.read( filename )
220: source.untaint
221:
222: # Create a new template object, set its path and filename, then tell it
223: # to parse the loaded source to define its behaviour. Parse is called
224: # after the file and path are set so directives in the template can
225: # use them.
226: obj = new()
227: obj._file = filename
228: obj._load_path.replace( path )
229: obj.parse( source )
230:
231: return obj
232: end
Create a new template object with the specified content (a String) and config hash. The config can contain one or more of the following keys:
# File lib/arrow/template.rb, line 305
305: def initialize( content=nil, config={} )
306: @config = Defaults.merge( config, &Arrow::HashMergeFunction )
307: @renderers = DefaultRenderers.dup
308: @attributes = {}
309: @syntax_tree = []
310: @source = content
311: @file = nil
312: @creation_time = Time.now
313: @load_path = self.class.load_path.dup
314: @prerender_done = false
315: @postrender_done = false
316:
317: @enclosing_templates = []
318:
319: case content
320: when String
321: self.parse( content )
322: when Array
323: self.install_syntax_tree( content )
324: when NilClass
325: # No-op
326: else
327: raise TemplateError,
328: "Can't handle a %s as template content" % content.class.name
329: end
330: end
Return the template that is enclosing the receiver in the current context, if any.
# File lib/arrow/template.rb, line 385
385: def _enclosing_template
386: self._enclosing_templates.last
387: end
Returns true if the source file from which the template was read has been modified since the receiver was instantiated. Always returns false if the template wasn‘t loaded from a file.
# File lib/arrow/template.rb, line 448
448: def changed?
449: return false unless @file
450:
451: if File.exists?( @file )
452: self.log.debug "Comparing creation time '%s' with file mtime '%s'" %
453: [ @creation_time, File.mtime(@file) ]
454: rval = File.mtime( @file ) > @creation_time
455: end
456:
457: self.log.debug "Template file '%s' has %s" %
458: [ @file, rval ? "changed" : "not changed" ]
459: return rval
460: end
Initialize a copy of the original template object.
# File lib/arrow/template.rb, line 334
334: def initialize_copy( original )
335: super
336:
337: @attributes = {}
338: tree = original._syntax_tree.collect {|node| node.clone}
339: self.install_syntax_tree( tree )
340: end
Return a human-readable representation of the template object.
# File lib/arrow/template.rb, line 391
391: def inspect
392: "#<%s:0x%0x %s (%d nodes)>" % [
393: self.class.name,
394: self.object_id * 2,
395: @file ? @file : '(anonymous)',
396: @syntax_tree.length,
397: ]
398: end
Install the given node into the template object.
# File lib/arrow/template.rb, line 429
429: def install_node( node )
430: #self.log.debug "Installing a %s %p" % [node.type, node]
431:
432: if node.respond_to?( :name ) && node.name
433: unless @attributes.key?( node.name )
434: #self.log.debug "Installing an attribute for a node named %p" % node.name
435: @attributes[ node.name ] = nil
436: self.add_attribute_accessor( node.name.intern )
437: self.add_attribute_mutator( node.name.intern )
438: else
439: #self.log.debug "Already have a attribute named %p" % node.name
440: end
441: end
442: end
Install a new syntax tree in the template object, replacing the old one, if any.
# File lib/arrow/template.rb, line 422
422: def install_syntax_tree( tree )
423: @syntax_tree = tree
424: @syntax_tree.each do |node| node.add_to_template(self) end
425: end
Create an anonymous module to act as a scope for any evals that take place during a single render.
# File lib/arrow/template.rb, line 536
536: def make_rendering_scope
537: # self.log.debug "Making rendering scope with attributes: %p" % [@attributes]
538: scope = RenderingScope.new( @attributes )
539: return scope
540: end
Return the approximate size of the template, in bytes. Used by Arrow::Cache for size thresholds.
# File lib/arrow/template.rb, line 403
403: def memsize
404: @source ? @source.length : 0
405: end
Parse the given template source (a String) and put the resulting nodes into the template‘s syntax_tree.
# File lib/arrow/template.rb, line 410
410: def parse( source )
411: @source = source
412: parserClass = @config[:parserClass]
413: tree = parserClass.new( @config ).parse( source, self )
414:
415: #self.log.debug "Parse complete: syntax tree is: %p" % tree
416: return self.install_syntax_tree( tree )
417: end
Clean up after template rendering, calling each of its nodes’ #after_rendering hook.
# File lib/arrow/template.rb, line 523
523: def postrender( enclosing_template=nil )
524: @syntax_tree.each do |node|
525: # self.log.debug " post-rendering %p" % [node]
526: node.after_rendering( self ) if
527: node.respond_to?( :after_rendering )
528: end
529: @enclosing_templates.pop
530: end
Returns true if this template has already been through a post-render.
# File lib/arrow/template.rb, line 516
516: def postrender_done?
517: return @postrender_done
518: end
Prep the template for rendering, calling each of its nodes’ #before_rendering hook.
# File lib/arrow/template.rb, line 471
471: def prerender( enclosing_template=nil )
472: @enclosing_templates << enclosing_template
473:
474: @syntax_tree.each do |node|
475: # self.log.debug " pre-rendering %p" % [node]
476: node.before_rendering( self ) if
477: node.respond_to?( :before_rendering )
478: end
479: end
Returns true if this template has already been through a pre-render.
# File lib/arrow/template.rb, line 464
464: def prerender_done?
465: return @prerender_done
466: end
Render the template to text and return it as a String. If called with an Array of nodes, the template will render them instead of its own syntax_tree. If given a scope (a Module object), a Binding of its internal state it will be used as the context of evaluation for the render. If not specified, a new anonymous Module instance is created for the render. If a enclosing_template is given, make it available during rendering for variable-sharing, etc. Returns the results of each nodes’ render joined together with the default string separator (+$,+).
# File lib/arrow/template.rb, line 491
491: def render( nodes=nil, scope=nil, enclosing_template=nil )
492: rval = []
493: nodes ||= self.get_prepped_nodes
494: scope ||= self.make_rendering_scope
495:
496: self.prerender( enclosing_template )
497:
498: # Render each node
499: nodes.each do |node|
500: # self.log.debug " rendering %p" % [ node ]
501: begin
502: rval << node.render( self, scope )
503: rescue ::Exception => err
504: rval << err
505: end
506: end
507:
508: return self.render_objects( *rval )
509: ensure
510: self.postrender
511: end
Render the given message as a comment as specified by the template configuration.
# File lib/arrow/template.rb, line 575
575: def render_comment( message )
576: comment = "%s%s%s\n" % [
577: @config[:commentStart],
578: message,
579: @config[:commentEnd],
580: ]
581: #self.log.debug "Rendered comment: %s" % comment
582: return comment
583: end
Render the specified objects into text.
# File lib/arrow/template.rb, line 544
544: def render_objects( *objs )
545: objs.collect do |obj|
546: rval = nil
547: key = (@renderers.keys & obj.class.ancestors).sort {|a,b| a <=> b}.first
548:
549: begin
550: if key
551: case @renderers[ key ]
552: when Proc, Method
553: rval = @renderers[ key ].call( obj, self )
554: when Symbol
555: methodname = @renderers[ key ]
556: rval = obj.send( methodname )
557: else
558: raise TypeError, "Unknown renderer type '%s' for %p" %
559: [ @renderers[key], obj ]
560: end
561: else
562: rval = obj.to_s
563: end
564: rescue => err
565: self.log.error "rendering error while rendering %p (a %s): %s" %
566: [obj, obj.class.name, err.message]
567: @renderers[ ::Exception ].call( err, self )
568: end
569: end.join
570: end
Call the given block, overriding the contents of the template‘s attributes and the definitions in the specified scope with those from the pairs in the given hash.
# File lib/arrow/template.rb, line 589
589: def with_overridden_attributes( scope, hash )
590: oldvals = {}
591: begin
592: hash.each do |name, value|
593: #self.log.debug "Overriding attribute %s with value: %p" %
594: # [ name, value ]
595: oldvals[name] = @attributes.key?( name ) ? @attributes[ name ] : nil
596: @attributes[ name ] = value
597: end
598: scope.override( hash ) do
599: yield( self )
600: end
601: ensure
602: oldvals.each do |name, value|
603: #self.log.debug "Restoring old value: %s for attribute %p" %
604: # [ name, value ]
605: @attributes.delete( name )
606: @attributes[ name ] = oldvals[name] if oldvals[name]
607: end
608: end
609: end
Add a singleton accessor (getter) method for accessing the attribute specified by sym to the receiver.
# File lib/arrow/template.rb, line 689
689: def add_attribute_accessor( sym )
690: name = sym.to_s.sub( /=$/, '' )
691:
692: code = %Q{
693: def self::#{name}
694: @attributes[#{name.inspect}]
695: end
696: }
697:
698: # $stderr.puts "Auto-defining accessor for #{name}: #{code}"
699: eval( code, nil, "#{name} [Auto-defined]", __LINE__ )
700: end
Add a singleton mutator (setter) method for accessing the attribute specified by sym to the receiver.
# File lib/arrow/template.rb, line 705
705: def add_attribute_mutator( sym )
706: name = sym.to_s.sub( /=$/, '' )
707:
708: code = %Q{
709: def self::#{name}=( arg )
710: @attributes[ #{name.inspect} ] = arg
711: end
712: }
713:
714: # $stderr.puts "Auto-defining mutator for #{name}: #{code}"
715: eval( code, nil, "#{name}= [Auto-defined]", __LINE__ )
716: end
Returns the syntax tree with its nodes prerendered in accordance with the template‘s configuration.
# File lib/arrow/template.rb, line 619
619: def get_prepped_nodes
620: tree = @syntax_tree.dup
621:
622: self.strip_directive_whitespace( tree ) if
623: @config[:elideDirectiveLines]
624:
625: return tree
626: end
Autoload accessor/mutator methods for attributes.
# File lib/arrow/template.rb, line 665
665: def method_missing( sym, *args, &block )
666: name = sym.to_s.gsub( /=$/, '' )
667: super unless @attributes.key?( name ) || !@config[:strictAttributes]
668:
669: #self.log.debug "Autoloading for #{sym}"
670:
671: # Mutator
672: if /=$/ =~ sym.to_s
673: #self.log.debug "Autoloading mutator %p" % sym
674: self.add_attribute_mutator( sym )
675: # Accessor
676: else
677: #self.log.debug "Autoloading accessor %p" % sym
678: self.add_attribute_accessor( sym )
679: end
680:
681: # Don't use #send to avoid infinite recursion in case method
682: # definition has failed for some reason.
683: self.method( sym ).call( *args )
684: end
Strip whitespace from the tails of textnodes before and the head of textnodes after lines consisting only of non-rendering directives in the given template syntax tree.
# File lib/arrow/template.rb, line 632
632: def strip_directive_whitespace( tree )
633: # Make a flat list of all nodes
634: nodes = tree.collect {|node| node.to_a}.flatten
635:
636: # Elide non-rendering directive lines. Match node lists like:
637: # <TextNode> =~ /\n\s*$/
638: # <NonRenderingNode>*
639: # <TextNode> =~ /^\n/
640: # removing one "\n" from the tail of the leading textnode and the
641: # head of the trailing textnode. Trailing textnode can also be a
642: # leading textnode for another series.
643: nodes.each_with_index do |node,i|
644: leadingNode = nodes[i-1]
645:
646: # If both the leading node and the current one match the
647: # criteria, look for a trailing node.
648: if i.nonzero? && leadingNode.is_a?( TextNode ) &&
649: leadingNode =~ /\n\s*$/s
650:
651: # Find the trailing node. Abandon the search on any
652: # rendering directive or text node that includes a blank line.
653: trailingNode = nodes[i..-1].find do |node|
654: break nil if node.rendering?
655: node.is_a?( TextNode ) && node =~ /^\n/
656: end
657:
658: leadingNode.body.sub!( /\n\s*$/, '' ) if trailingNode
659: end
660: end
661: end
--- SEC00145
--- ""
--- | Module <a href="Template/ConditionalDirective.html" class="link">Arrow::Template::ConditionalDirective</a><br /> Class <a href="Template/AttributeDirective.html" class="link">Arrow::Template::AttributeDirective</a><br /> Class <a href="Template/BracketingDirective.html" class="link">Arrow::Template::BracketingDirective</a><br /> Class <a href="Template/CommentNode.html" class="link">Arrow::Template::CommentNode</a><br /> Class <a href="Template/Directive.html" class="link">Arrow::Template::Directive</a><br /> Class <a href="Template/Node.html" class="link">Arrow::Template::Node</a><br /> Class <a href="Template/RenderingScope.html" class="link">Arrow::Template::RenderingScope</a><br /> Class <a href="Template/TextNode.html" class="link">Arrow::Template::TextNode</a><br />
--- - name: load_path rw: RW a_desc: ""
---
- methods:
- visibility: public
aref: M000441
name: attr_underbarred_accessor
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 264</span>\n\
264: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-keyword kw\">self</span><span class=\"ruby-operator\">::</span><span class=\"ruby-identifier\">attr_underbarred_accessor</span>( <span class=\"ruby-identifier\">sym</span> )\n\
265: <span class=\"ruby-identifier\">ivarname</span> = <span class=\"ruby-value str\">'@'</span> <span class=\"ruby-operator\">+</span> <span class=\"ruby-identifier\">sym</span>.<span class=\"ruby-identifier\">to_s</span>.<span class=\"ruby-identifier\">gsub</span>( <span class=\"ruby-regexp re\">/^_+/</span>, <span class=\"ruby-value str\">''</span> )\n\
266: <span class=\"ruby-identifier\">define_method</span>( <span class=\"ruby-identifier\">sym</span> ) {\n\
267: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">instance_variable_get</span>( <span class=\"ruby-identifier\">ivarname</span> )\n\
268: }\n\
269: <span class=\"ruby-identifier\">define_method</span>( <span class=\"ruby-node\">"#{sym}="</span> ) {<span class=\"ruby-operator\">|</span><span class=\"ruby-identifier\">arg</span><span class=\"ruby-operator\">|</span>\n\
270: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">instance_variable_set</span>( <span class=\"ruby-identifier\">ivarname</span>, <span class=\"ruby-identifier\">arg</span> )\n\
271: }\n\
272: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Create an attr_accessor method for the specified <tt>sym</tt>, but one
which will look for instance variables with any leading underbars removed.
</p>
params: ( sym )
- visibility: public
aref: M000440
name: attr_underbarred_reader
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 254</span>\n\
254: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-keyword kw\">self</span><span class=\"ruby-operator\">::</span><span class=\"ruby-identifier\">attr_underbarred_reader</span>( <span class=\"ruby-identifier\">sym</span> )\n\
255: <span class=\"ruby-identifier\">ivarname</span> = <span class=\"ruby-value str\">'@'</span> <span class=\"ruby-operator\">+</span> <span class=\"ruby-identifier\">sym</span>.<span class=\"ruby-identifier\">to_s</span>.<span class=\"ruby-identifier\">gsub</span>( <span class=\"ruby-regexp re\">/^_+/</span>, <span class=\"ruby-value str\">''</span> )\n\
256: <span class=\"ruby-identifier\">define_method</span>( <span class=\"ruby-identifier\">sym</span> ) {\n\
257: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">instance_variable_get</span>( <span class=\"ruby-identifier\">ivarname</span> )\n\
258: }\n\
259: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Create an attr_reader method for the specified <tt>sym</tt>, but one which
will look for instance variables with any leading underbars removed.
</p>
params: ( sym )
- visibility: public
aref: M000439
name: find_file
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 237</span>\n\
237: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-keyword kw\">self</span><span class=\"ruby-operator\">::</span><span class=\"ruby-identifier\">find_file</span>( <span class=\"ruby-identifier\">file</span>, <span class=\"ruby-identifier\">path</span>=[] )\n\
238: <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">TemplateError</span>, <span class=\"ruby-node\">"Filename #{file} is tainted."</span> <span class=\"ruby-keyword kw\">if</span>\n\
239: <span class=\"ruby-identifier\">file</span>.<span class=\"ruby-identifier\">tainted?</span>\n\
240: \n\
241: <span class=\"ruby-identifier\">filename</span> = <span class=\"ruby-identifier\">path</span>.\n\
242: <span class=\"ruby-identifier\">collect</span> {<span class=\"ruby-operator\">|</span><span class=\"ruby-identifier\">dir</span><span class=\"ruby-operator\">|</span> <span class=\"ruby-constant\">File</span>.<span class=\"ruby-identifier\">expand_path</span>(<span class=\"ruby-identifier\">file</span>, <span class=\"ruby-identifier\">dir</span>).<span class=\"ruby-identifier\">untaint</span> }.\n\
243: <span class=\"ruby-identifier\">find</span> {<span class=\"ruby-operator\">|</span><span class=\"ruby-identifier\">fn</span><span class=\"ruby-operator\">|</span> <span class=\"ruby-constant\">File</span>.<span class=\"ruby-identifier\">file?</span>(<span class=\"ruby-identifier\">fn</span>) }\n\
244: <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">TemplateError</span>,\n\
245: <span class=\"ruby-value str\">"Template '%s' not found. Search path was %p"</span> <span class=\"ruby-operator\">%</span>\n\
246: [ <span class=\"ruby-identifier\">file</span>, <span class=\"ruby-identifier\">path</span> ] <span class=\"ruby-keyword kw\">unless</span> <span class=\"ruby-identifier\">filename</span>\n\
247: \n\
248: <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">filename</span>\n\
249: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Find the specified <tt>file</tt> in the given <tt>path</tt> (or the <a
href="Template.html">Template</a> class‘s #load_path if not
specified).
</p>
params: ( file, path=[] )
- visibility: public
aref: M000438
name: load
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 209</span>\n\
209: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-keyword kw\">self</span><span class=\"ruby-operator\">::</span><span class=\"ruby-identifier\">load</span>( <span class=\"ruby-identifier\">name</span>, <span class=\"ruby-identifier\">path</span>=[] )\n\
210: \n\
211: <span class=\"ruby-comment cmt\"># Find the file on either the specified or default path</span>\n\
212: <span class=\"ruby-identifier\">path</span> = <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">load_path</span> <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">path</span>.<span class=\"ruby-identifier\">empty?</span>\n\
213: <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">Logger</span>[<span class=\"ruby-keyword kw\">self</span>].<span class=\"ruby-identifier\">debug</span> <span class=\"ruby-value str\">"Searching for template '%s' in %d directories"</span> <span class=\"ruby-operator\">%</span>\n\
214: [ <span class=\"ruby-identifier\">name</span>, <span class=\"ruby-identifier\">path</span>.<span class=\"ruby-identifier\">size</span> ]\n\
215: <span class=\"ruby-identifier\">filename</span> = <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">find_file</span>( <span class=\"ruby-identifier\">name</span>, <span class=\"ruby-identifier\">path</span> )\n\
216: <span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">Logger</span>[<span class=\"ruby-keyword kw\">self</span>].<span class=\"ruby-identifier\">debug</span> <span class=\"ruby-value str\">"Found '%s'"</span> <span class=\"ruby-operator\">%</span> [ <span class=\"ruby-identifier\">filename</span> ]\n\
217: \n\
218: <span class=\"ruby-comment cmt\"># Read the template source</span>\n\
219: <span class=\"ruby-identifier\">source</span> = <span class=\"ruby-constant\">File</span>.<span class=\"ruby-identifier\">read</span>( <span class=\"ruby-identifier\">filename</span> )\n\
220: <span class=\"ruby-identifier\">source</span>.<span class=\"ruby-identifier\">untaint</span>\n\
221: \n\
222: <span class=\"ruby-comment cmt\"># Create a new template object, set its path and filename, then tell it</span>\n\
223: <span class=\"ruby-comment cmt\"># to parse the loaded source to define its behaviour. Parse is called</span>\n\
224: <span class=\"ruby-comment cmt\"># after the file and path are set so directives in the template can</span>\n\
225: <span class=\"ruby-comment cmt\"># use them.</span>\n\
226: <span class=\"ruby-identifier\">obj</span> = <span class=\"ruby-identifier\">new</span>()\n\
227: <span class=\"ruby-identifier\">obj</span>.<span class=\"ruby-identifier\">_file</span> = <span class=\"ruby-identifier\">filename</span>\n\
228: <span class=\"ruby-identifier\">obj</span>.<span class=\"ruby-identifier\">_load_path</span>.<span class=\"ruby-identifier\">replace</span>( <span class=\"ruby-identifier\">path</span> )\n\
229: <span class=\"ruby-identifier\">obj</span>.<span class=\"ruby-identifier\">parse</span>( <span class=\"ruby-identifier\">source</span> )\n\
230: \n\
231: <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">obj</span>\n\
232: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Load a template from a file.
</p>
params: ( name, path=[] )
- visibility: public
aref: M000442
name: new
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 305</span>\n\
305: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">initialize</span>( <span class=\"ruby-identifier\">content</span>=<span class=\"ruby-keyword kw\">nil</span>, <span class=\"ruby-identifier\">config</span>={} )\n\
306: <span class=\"ruby-ivar\">@config</span> = <span class=\"ruby-constant\">Defaults</span>.<span class=\"ruby-identifier\">merge</span>( <span class=\"ruby-identifier\">config</span>, <span class=\"ruby-operator\">&</span><span class=\"ruby-constant\">Arrow</span><span class=\"ruby-operator\">::</span><span class=\"ruby-constant\">HashMergeFunction</span> )\n\
307: <span class=\"ruby-ivar\">@renderers</span> = <span class=\"ruby-constant\">DefaultRenderers</span>.<span class=\"ruby-identifier\">dup</span>\n\
308: <span class=\"ruby-ivar\">@attributes</span> = {}\n\
309: <span class=\"ruby-ivar\">@syntax_tree</span> = []\n\
310: <span class=\"ruby-ivar\">@source</span> = <span class=\"ruby-identifier\">content</span>\n\
311: <span class=\"ruby-ivar\">@file</span> = <span class=\"ruby-keyword kw\">nil</span>\n\
312: <span class=\"ruby-ivar\">@creation_time</span> = <span class=\"ruby-constant\">Time</span>.<span class=\"ruby-identifier\">now</span>\n\
313: <span class=\"ruby-ivar\">@load_path</span> = <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">class</span>.<span class=\"ruby-identifier\">load_path</span>.<span class=\"ruby-identifier\">dup</span>\n\
314: <span class=\"ruby-ivar\">@prerender_done</span> = <span class=\"ruby-keyword kw\">false</span>\n\
315: <span class=\"ruby-ivar\">@postrender_done</span> = <span class=\"ruby-keyword kw\">false</span>\n\
316: \n\
317: <span class=\"ruby-ivar\">@enclosing_templates</span> = []\n\
318: \n\
319: <span class=\"ruby-keyword kw\">case</span> <span class=\"ruby-identifier\">content</span>\n\
320: <span class=\"ruby-keyword kw\">when</span> <span class=\"ruby-constant\">String</span>\n\
321: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">parse</span>( <span class=\"ruby-identifier\">content</span> )\n\
322: <span class=\"ruby-keyword kw\">when</span> <span class=\"ruby-constant\">Array</span>\n\
323: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">install_syntax_tree</span>( <span class=\"ruby-identifier\">content</span> )\n\
324: <span class=\"ruby-keyword kw\">when</span> <span class=\"ruby-constant\">NilClass</span>\n\
325: <span class=\"ruby-comment cmt\"># No-op</span>\n\
326: <span class=\"ruby-keyword kw\">else</span>\n\
327: <span class=\"ruby-identifier\">raise</span> <span class=\"ruby-constant\">TemplateError</span>,\n\
328: <span class=\"ruby-value str\">"Can't handle a %s as template content"</span> <span class=\"ruby-operator\">%</span> <span class=\"ruby-identifier\">content</span>.<span class=\"ruby-identifier\">class</span>.<span class=\"ruby-identifier\">name</span>\n\
329: <span class=\"ruby-keyword kw\">end</span>\n\
330: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Create a <a href="Template.html#M000442">new</a> template object with the
specified <tt>content</tt> (a <a href="../String.html">String</a>) and
<tt>config</tt> hash. The <tt>config</tt> can contain one or more of the
following keys:
</p>
<dl>
<dt><b>:parserClass</b></dt><dd>The class object that will be instantiated to <a
href="Template.html#M000447">parse</a> the template text into nodes.
Defaults to <a href="Template/Parser.html">Arrow::Template::Parser</a>.
</dd>
<dt><b>:elideDirectiveLines</b></dt><dd>If set to a <tt>true</tt> value, lines of the template which contain only
whitespace and one or more non-rendering directives will be discarded from
the rendered output.
</dd>
<dt><b>:debuggingComments</b></dt><dd>If set to a <tt>true</tt> value, nodes which are set up to do so will
insert a comment with debugging information immediately before their
rendered output.
</dd>
<dt><b>:commentStart</b></dt><dd>The <a href="../String.html">String</a> which will be prepended to all
comments rendered in the output. See <a
href="Template.html#M000461">#render_comment</a>.
</dd>
<dt><b>:commentEnd</b></dt><dd>The <a href="../String.html">String</a> which will be appended to all
comments rendered in the output. See <a
href="Template.html#M000461">#render_comment</a>.
</dd>
<dt><b>:strictAttributes</b></dt><dd>If set to a <tt>true</tt> value, method calls which don‘t match
already-extant attributes will result in NameErrors. This is <tt>false</tt>
by default, which causes method calls to generate attributes with the same
name.
</dd>
</dl>
params: ( content=nil, config={} )
category: Class
type: Public
- methods:
- visibility: public
aref: M000444
name: _enclosing_template
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 385</span>\n\
385: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">_enclosing_template</span>\n\
386: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">_enclosing_templates</span>.<span class=\"ruby-identifier\">last</span>\n\
387: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Return the template that is enclosing the receiver in the current context,
if any.
</p>
params: ()
- visibility: public
aref: M000458
name: after_rendering
m_desc: |-
<p>
Alias for <a href="Template.html#M000457">#postrender</a>
</p>
params: ( enclosing_template=nil )
- visibility: public
aref: M000453
name: before_rendering
m_desc: |-
<p>
Alias for <a href="Template.html#M000452">#prerender</a>
</p>
params: ( enclosing_template=nil )
- visibility: public
aref: M000450
name: changed?
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 448</span>\n\
448: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">changed?</span>\n\
449: <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">false</span> <span class=\"ruby-keyword kw\">unless</span> <span class=\"ruby-ivar\">@file</span>\n\
450: \n\
451: <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-constant\">File</span>.<span class=\"ruby-identifier\">exists?</span>( <span class=\"ruby-ivar\">@file</span> )\n\
452: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">log</span>.<span class=\"ruby-identifier\">debug</span> <span class=\"ruby-value str\">"Comparing creation time '%s' with file mtime '%s'"</span> <span class=\"ruby-operator\">%</span>\n\
453: [ <span class=\"ruby-ivar\">@creation_time</span>, <span class=\"ruby-constant\">File</span>.<span class=\"ruby-identifier\">mtime</span>(<span class=\"ruby-ivar\">@file</span>) ]\n\
454: <span class=\"ruby-identifier\">rval</span> = <span class=\"ruby-constant\">File</span>.<span class=\"ruby-identifier\">mtime</span>( <span class=\"ruby-ivar\">@file</span> ) <span class=\"ruby-operator\">></span> <span class=\"ruby-ivar\">@creation_time</span>\n\
455: <span class=\"ruby-keyword kw\">end</span>\n\
456: \n\
457: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">log</span>.<span class=\"ruby-identifier\">debug</span> <span class=\"ruby-value str\">"Template file '%s' has %s"</span> <span class=\"ruby-operator\">%</span>\n\
458: [ <span class=\"ruby-ivar\">@file</span>, <span class=\"ruby-identifier\">rval</span> <span class=\"ruby-value\">? </span><span class=\"ruby-value str\">"changed"</span> <span class=\"ruby-operator\">:</span> <span class=\"ruby-value str\">"not changed"</span> ]\n\
459: <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">rval</span>\n\
460: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Returns <tt>true</tt> if the source file from which the template was read
has been modified since the receiver was instantiated. Always returns
<tt>false</tt> if the template wasn‘t loaded from a file.
</p>
params: ()
- visibility: public
aref: M000443
name: initialize_copy
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 334</span>\n\
334: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">initialize_copy</span>( <span class=\"ruby-identifier\">original</span> )\n\
335: <span class=\"ruby-keyword kw\">super</span>\n\
336: \n\
337: <span class=\"ruby-ivar\">@attributes</span> = {}\n\
338: <span class=\"ruby-identifier\">tree</span> = <span class=\"ruby-identifier\">original</span>.<span class=\"ruby-identifier\">_syntax_tree</span>.<span class=\"ruby-identifier\">collect</span> {<span class=\"ruby-operator\">|</span><span class=\"ruby-identifier\">node</span><span class=\"ruby-operator\">|</span> <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">clone</span>}\n\
339: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">install_syntax_tree</span>( <span class=\"ruby-identifier\">tree</span> )\n\
340: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Initialize a copy of the <tt>original</tt> template object.
</p>
params: ( original )
- visibility: public
aref: M000445
name: inspect
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 391</span>\n\
391: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">inspect</span>\n\
392: <span class=\"ruby-value str\">"#<%s:0x%0x %s (%d nodes)>"</span> <span class=\"ruby-operator\">%</span> [\n\
393: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">class</span>.<span class=\"ruby-identifier\">name</span>,\n\
394: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">object_id</span> <span class=\"ruby-operator\">*</span> <span class=\"ruby-value\">2</span>,\n\
395: <span class=\"ruby-ivar\">@file</span> <span class=\"ruby-operator\">?</span> <span class=\"ruby-ivar\">@file</span> <span class=\"ruby-operator\">:</span> <span class=\"ruby-value str\">'(anonymous)'</span>,\n\
396: <span class=\"ruby-ivar\">@syntax_tree</span>.<span class=\"ruby-identifier\">length</span>,\n\
397: ]\n\
398: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Return a human-readable representation of the template object.
</p>
params: ()
- visibility: public
aref: M000449
name: install_node
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 429</span>\n\
429: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">install_node</span>( <span class=\"ruby-identifier\">node</span> )\n\
430: <span class=\"ruby-comment cmt\">#self.log.debug "Installing a %s %p" % [node.type, node]</span>\n\
431: \n\
432: <span class=\"ruby-keyword kw\">if</span> <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">respond_to?</span>( <span class=\"ruby-identifier\">:name</span> ) <span class=\"ruby-operator\">&&</span> <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">name</span>\n\
433: <span class=\"ruby-keyword kw\">unless</span> <span class=\"ruby-ivar\">@attributes</span>.<span class=\"ruby-identifier\">key?</span>( <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">name</span> )\n\
434: <span class=\"ruby-comment cmt\">#self.log.debug "Installing an attribute for a node named %p" % node.name</span>\n\
435: <span class=\"ruby-ivar\">@attributes</span>[ <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">name</span> ] = <span class=\"ruby-keyword kw\">nil</span>\n\
436: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">add_attribute_accessor</span>( <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">name</span>.<span class=\"ruby-identifier\">intern</span> )\n\
437: <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">add_attribute_mutator</span>( <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">name</span>.<span class=\"ruby-identifier\">intern</span> )\n\
438: <span class=\"ruby-keyword kw\">else</span>\n\
439: <span class=\"ruby-comment cmt\">#self.log.debug "Already have a attribute named %p" % node.name</span>\n\
440: <span class=\"ruby-keyword kw\">end</span>\n\
441: <span class=\"ruby-keyword kw\">end</span>\n\
442: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Install the given <tt>node</tt> into the template object.
</p>
params: ( node )
- visibility: public
aref: M000448
name: install_syntax_tree
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 422</span>\n\
422: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">install_syntax_tree</span>( <span class=\"ruby-identifier\">tree</span> )\n\
423: <span class=\"ruby-ivar\">@syntax_tree</span> = <span class=\"ruby-identifier\">tree</span>\n\
424: <span class=\"ruby-ivar\">@syntax_tree</span>.<span class=\"ruby-identifier\">each</span> <span class=\"ruby-keyword kw\">do</span> <span class=\"ruby-operator\">|</span><span class=\"ruby-identifier\">node</span><span class=\"ruby-operator\">|</span> <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">add_to_template</span>(<span class=\"ruby-keyword kw\">self</span>) <span class=\"ruby-keyword kw\">end</span>\n\
425: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Install a <a href="Template.html#M000442">new</a> syntax tree in the
template object, replacing the old one, if any.
</p>
params: ( tree )
- visibility: public
aref: M000459
name: make_rendering_scope
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 536</span>\n\
536: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">make_rendering_scope</span>\n\
537: <span class=\"ruby-comment cmt\"># self.log.debug "Making rendering scope with attributes: %p" % [@attributes]</span>\n\
538: <span class=\"ruby-identifier\">scope</span> = <span class=\"ruby-constant\">RenderingScope</span>.<span class=\"ruby-identifier\">new</span>( <span class=\"ruby-ivar\">@attributes</span> )\n\
539: <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-identifier\">scope</span>\n\
540: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Create an anonymous module to act as a scope for any evals that take place
during a single <a href="Template.html#M000454">render</a>.
</p>
params: ()
- visibility: public
aref: M000446
name: memsize
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 403</span>\n\
403: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">memsize</span>\n\
404: <span class=\"ruby-ivar\">@source</span> <span class=\"ruby-operator\">?</span> <span class=\"ruby-ivar\">@source</span>.<span class=\"ruby-identifier\">length</span> <span class=\"ruby-operator\">:</span> <span class=\"ruby-value\">0</span>\n\
405: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Return the approximate size of the template, in bytes. Used by <a
href="Cache.html">Arrow::Cache</a> for size thresholds.
</p>
params: ()
- visibility: public
aref: M000447
name: parse
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 410</span>\n\
410: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">parse</span>( <span class=\"ruby-identifier\">source</span> )\n\
411: <span class=\"ruby-ivar\">@source</span> = <span class=\"ruby-identifier\">source</span>\n\
412: <span class=\"ruby-identifier\">parserClass</span> = <span class=\"ruby-ivar\">@config</span>[<span class=\"ruby-identifier\">:parserClass</span>]\n\
413: <span class=\"ruby-identifier\">tree</span> = <span class=\"ruby-identifier\">parserClass</span>.<span class=\"ruby-identifier\">new</span>( <span class=\"ruby-ivar\">@config</span> ).<span class=\"ruby-identifier\">parse</span>( <span class=\"ruby-identifier\">source</span>, <span class=\"ruby-keyword kw\">self</span> )\n\
414: \n\
415: <span class=\"ruby-comment cmt\">#self.log.debug "Parse complete: syntax tree is: %p" % tree</span>\n\
416: <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-keyword kw\">self</span>.<span class=\"ruby-identifier\">install_syntax_tree</span>( <span class=\"ruby-identifier\">tree</span> )\n\
417: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Parse the given template source (a <a href="../String.html">String</a>) and
put the resulting nodes into the template‘s syntax_tree.
</p>
params: ( source )
- visibility: public
aref: M000457
name: postrender
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 523</span>\n\
523: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">postrender</span>( <span class=\"ruby-identifier\">enclosing_template</span>=<span class=\"ruby-keyword kw\">nil</span> )\n\
524: <span class=\"ruby-ivar\">@syntax_tree</span>.<span class=\"ruby-identifier\">each</span> <span class=\"ruby-keyword kw\">do</span> <span class=\"ruby-operator\">|</span><span class=\"ruby-identifier\">node</span><span class=\"ruby-operator\">|</span>\n\
525: <span class=\"ruby-comment cmt\"># self.log.debug " post-rendering %p" % [node]</span>\n\
526: <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">after_rendering</span>( <span class=\"ruby-keyword kw\">self</span> ) <span class=\"ruby-keyword kw\">if</span>\n\
527: <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">respond_to?</span>( <span class=\"ruby-identifier\">:after_rendering</span> )\n\
528: <span class=\"ruby-keyword kw\">end</span>\n\
529: <span class=\"ruby-ivar\">@enclosing_templates</span>.<span class=\"ruby-identifier\">pop</span>\n\
530: <span class=\"ruby-keyword kw\">end</span>"
aka:
- aref: Template.html#M000458
name: after_rendering
m_desc: |-
<p>
Clean up after template rendering, calling each of its nodes’ <a
href="Template.html#M000458">#after_rendering</a> hook.
</p>
params: ( enclosing_template=nil )
- visibility: public
aref: M000456
name: postrender_done?
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 516</span>\n\
516: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">postrender_done?</span>\n\
517: <span class=\"ruby-keyword kw\">return</span> <span class=\"ruby-ivar\">@postrender_done</span>\n\
518: <span class=\"ruby-keyword kw\">end</span>"
m_desc: |-
<p>
Returns <tt>true</tt> if this template has already been through a post-<a
href="Template.html#M000454">render</a>.
</p>
params: ()
- visibility: public
aref: M000452
name: prerender
sourcecode: " <span class=\"ruby-comment cmt\"># File lib/arrow/template.rb, line 471</span>\n\
471: <span class=\"ruby-keyword kw\">def</span> <span class=\"ruby-identifier\">prerender</span>( <span class=\"ruby-identifier\">enclosing_template</span>=<span class=\"ruby-keyword kw\">nil</span> )\n\
472: <span class=\"ruby-ivar\">@enclosing_templates</span> <span class=\"ruby-operator\"><<</span> <span class=\"ruby-identifier\">enclosing_template</span>\n\
473: \n\
474: <span class=\"ruby-ivar\">@syntax_tree</span>.<span class=\"ruby-identifier\">each</span> <span class=\"ruby-keyword kw\">do</span> <span class=\"ruby-operator\">|</span><span class=\"ruby-identifier\">node</span><span class=\"ruby-operator\">|</span>\n\
475: <span class=\"ruby-comment cmt\"># self.log.debug " pre-rendering %p" % [node]</span>\n\
476: <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">before_rendering</span>( <span class=\"ruby-keyword kw\">self</span> ) <span class=\"ruby-keyword kw\">if</span>\n\
477: <span class=\"ruby-identifier\">node</span>.<span class=\"ruby-identifier\">respond_to?</span>( <span class=\"ruby-identifier\">:before_rendering</span> )\n\
47