Class: Inversion::Template::ForTag

Inherits:
CodeTag show all
Includes:
ContainerTag
Defined in:
lib/inversion/template/fortag.rb

Overview

Inversion ‘for’ tag.

Iteration tag for outputting a template part for each member of a collection (i.e., an object that is Enumerable).

Syntax

<?for var in attribute ?>
<?for var in attribute.methodchain ?>
<?for var1, var2 in attribute.methodchain ?>

Examples

<?for employee in company.employees ?>

Hey <?call employee.name ?>! You're fired!

<?end ?>

Constant Summary

Constants inherited from Tag

Tag::TAG_PLUGIN_PATTERN

Instance Attribute Summary collapse

Attributes included from ContainerTag

#subnodes

Attributes inherited from CodeTag

#body, #identifiers

Attributes inherited from Tag

#body

Attributes inherited from Node

#colnum, #linenum

Instance Method Summary collapse

Methods included from ContainerTag

#<<, #is_container?, #render_subnodes

Methods inherited from CodeTag

inherit_tag_patterns, tag_pattern, tag_patterns

Methods included from AbstractClass

included

Methods included from AbstractClass::ClassMethods

#inherited, #pure_virtual

Methods inherited from Tag

create, #derivatives, inherited, load, load_all, #tagname, types, #types

Methods included from MethodUtilities

#singleton_attr_accessor, #singleton_attr_reader, #singleton_attr_writer

Methods inherited from Node

#after_appending, #after_rendering, #before_appending, #before_rendering, #is_container?, #location

Constructor Details

#initialize(body, linenum = nil, colnum = nil) ⇒ ForTag

Create a new ForTag with the specified ‘body`.



62
63
64
65
66
67
# File 'lib/inversion/template/fortag.rb', line 62

def initialize( body, linenum=nil, colnum=nil )
  @block_args = []
  @enumerator = nil

  super( 'for ' + body, linenum, colnum )
end

Instance Attribute Details

#block_argsObject

The array of attribute names that will be assigned to the rendering scope by the block for each iteration



76
77
78
# File 'lib/inversion/template/fortag.rb', line 76

def block_args
  @block_args
end

#enumeratorObject

The attribute or methodchain that yields the enumerable object



79
80
81
# File 'lib/inversion/template/fortag.rb', line 79

def enumerator
  @enumerator
end

Instance Method Details

#as_comment_bodyObject

Render the tag as the body of a comment, suitable for template debugging.



115
116
117
118
119
120
121
122
123
# File 'lib/inversion/template/fortag.rb', line 115

def as_comment_body
  comment = "%s: { %s IN template.%s }" % [
    self.tagname,
    self.block_args.join(', '),
    self.enumerator
  ]

  return comment
end

#render(state) ⇒ Object

Iterate over the enumerator in ‘state` and render the tag’s contents for each iteration.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/inversion/template/fortag.rb', line 84

def render( state )
  lvalue = state.eval( self.enumerator ) or return nil
  lvalue = lvalue.each unless lvalue.respond_to?( :next )

  self.log.debug "Rendering %p via block args: %p" % [ lvalue, self.block_args ]

  # Loop will exit as soon as the Enumerator runs out of elements
  loop do
    args = lvalue.next

    # Turn the block arguments into an overrides hash by zipping up
    # the arguments names and values
    overrides = if self.block_args.size > 1
        args = [ args ] unless args.is_a?( Array )
        Hash[ self.block_args.zip(args) ]
      else
        { self.block_args.first => args }
      end

    # Overlay the block args from the 'for' over the template attributes and render
    # each subnode
    state.with_attributes( overrides ) do
      super
    end
  end

  return nil
end