Inversion::Template::

ForTag class

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

Attributes

block_args RW

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

enumerator RW

The attribute or methodchain that yields the enumerable object

Public Class Methods

new( body, linenum=nil, colnum=nil )

Create a new ForTag with the specified ‘body`.

# File lib/inversion/template/fortag.rb, line 61
def initialize( body, linenum=nil, colnum=nil )
        @block_args = []
        @enumerator = nil

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

Public Instance Methods

as_comment_body()

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

# File lib/inversion/template/fortag.rb, line 114
def as_comment_body
        comment = "%s: { %s IN template.%s }" % [
                self.tagname,
                self.block_args.join(', '),
                self.enumerator
        ]

        return comment
end
render( state )

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

# File lib/inversion/template/fortag.rb, line 83
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