Subversion Info

Rev
406
Last Checked In
2007-07-18 17:01:59 (7 months ago)
Checked in by
bbleything

Parent

Class Index

Quicksearch

Arrow::Template

The default template class for Arrow.

Constants

SVNRev
SVN Revision
SVNId
SVN Id
Defaults
Configuration defaults. Valid members are the same as those listed for the config item of the #new method.
DefaultRenderers
A Hash which specifies the default renderers for different classes of objects.

Attributes

load_path[RW]

(Not documented)

Public Class Methods

attr_underbarred_accessor( sym ) click to toggle source

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
attr_underbarred_reader( sym ) click to toggle source

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_file( file, path=[] ) click to toggle source

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( name, path=[] ) click to toggle source

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
new( content=nil, config={} ) click to toggle source

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:

:parserClass
The class object that will be instantiated to parse the template text into nodes. Defaults to Arrow::Template::Parser.
:elideDirectiveLines
If set to a true value, lines of the template which contain only whitespace and one or more non-rendering directives will be discarded from the rendered output.
:debuggingComments
If set to a true value, nodes which are set up to do so will insert a comment with debugging information immediately before their rendered output.
:commentStart
The String which will be prepended to all comments rendered in the output. See #render_comment.
:commentEnd
The String which will be appended to all comments rendered in the output. See #render_comment.
:strictAttributes
If set to a true value, method calls which don‘t match already-extant attributes will result in NameErrors. This is false by default, which causes method calls to generate attributes with the same name.

     # 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

Public Instance Methods

_enclosing_template() click to toggle source

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
after_rendering( enclosing_template=nil ) click to toggle source

Alias for #postrender

before_rendering( enclosing_template=nil ) click to toggle source

Alias for #prerender

changed?() click to toggle source

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_copy( original ) click to toggle source

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
inspect() click to toggle source

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_node( node ) click to toggle source

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_syntax_tree( tree ) click to toggle source

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
make_rendering_scope() click to toggle source

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
memsize() click to toggle source

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( source ) click to toggle source

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
postrender( enclosing_template=nil ) click to toggle source

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
Also aliased as: after_rendering
postrender_done?() click to toggle source

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
prerender( enclosing_template=nil ) click to toggle source

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
Also aliased as: before_rendering
prerender_done?() click to toggle source

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( nodes=nil, scope=nil, enclosing_template=nil ) click to toggle source

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
Also aliased as: to_s
render_comment( message ) click to toggle source

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_objects( *objs ) click to toggle source

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
to_s( nodes=nil, scope=nil, enclosing_template=nil ) click to toggle source

Alias for #render

with_overridden_attributes( scope, hash ) {|self| ...} click to toggle source

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

Protected Instance Methods

add_attribute_accessor( sym ) click to toggle source

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_attribute_mutator( sym ) click to toggle source

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
get_prepped_nodes() click to toggle source

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
method_missing( sym, *args, &block ) click to toggle source

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_directive_whitespace( tree ) click to toggle source

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

secsequence

--- SEC00145

seccomment

--- ""

classlist

--- |
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 />

attributes

--- 
- name: load_path
  rw: RW
  a_desc: ""

method_list

--- 
- 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\">&quot;#{sym}=&quot;</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\">&quot;Filename #{file} is tainted.&quot;</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\">&quot;Template '%s' not found. Search path was %p&quot;</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&#8216;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\">&quot;Searching for template '%s' in %d directories&quot;</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\">&quot;Found '%s'&quot;</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\">&amp;</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\">&quot;Can't handle a %s as template content&quot;</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&#8216;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\">&quot;Comparing creation time '%s' with file mtime '%s'&quot;</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\">&gt;</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\">&quot;Template file '%s' has %s&quot;</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\">&quot;changed&quot;</span> <span class=\"ruby-operator\">:</span> <span class=\"ruby-value str\">&quot;not changed&quot;</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&#8216;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\">&quot;#&lt;%s:0x%0x %s (%d nodes)&gt;&quot;</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 &quot;Installing a %s %p&quot; % [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\">&amp;&amp;</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 &quot;Installing an attribute for a node named %p&quot; % 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 &quot;Already have a attribute named %p&quot; % 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 &quot;Making rendering scope with attributes: %p&quot; % [@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 &quot;Parse complete: syntax tree is: %p&quot; % 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&#8216;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 &quot;    post-rendering %p&quot; % [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&#8217; <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\">&lt;&lt;</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 &quot;    pre-rendering %p&quot; % [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