Class: H2o::Tags::Recurse

Inherits:
Tag show all
Defined in:
lib/h2o/tags/recurse.rb

Overview

Recurse tag allows rendering of tree structures. The template should look something like this: recurse all_categories with children as category %

<ul>
  {% loop %}
    <li>
      <h{{ level }}>{{ category.title }}</h{{ level }}>
      {% children %}
    </li>
  {% endloop %}
</ul>

endrecurse %

Constant Summary collapse

Syntax =
/(#{H2o::NAME_RE})\s+with\s+(#{H2o::IDENTIFIER_RE})\s+as\s+(#{H2o::IDENTIFIER_RE})/

Instance Method Summary collapse

Constructor Details

#initialize(parser, argstring) ⇒ Recurse

Returns a new instance of Recurse.



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/h2o/tags/recurse.rb', line 18

def initialize(parser, argstring)
  @body    = parser.parse(:loop, :children, :endloop, :endrecurse)
  @child   = parser.parse(:children, :endloop, :endrecurse) if parser.token && parser.token.include?('loop')
  @enditem = parser.parse(:endloop, :endrecurse) if parser.token && parser.token.include?('children')
  @end     = parser.parse(:endrecurse) if parser.token && parser.token.include?('endloop')        
  if argstring =~ Syntax
    @collection_id   = $1.to_sym
    @children_method = $2.to_sym
    @item_id         = $3.to_sym
  else
    raise SyntaxError, "Invalid recurse syntax "
  end
end

Instance Method Details

#render(context, stream) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/h2o/tags/recurse.rb', line 32

def render(context, stream)
  collection = context.resolve(@collection_id)
  @body.render(context, stream)
  context.stack do
    level = context[:level] || 1
    collection.each do |item|
      context[@item_id] = item
      context[:level] = level
      @child.render(context, stream)
      children = item.respond_to?(@children_method) ? item.send(@children_method) : item[@children_method]
      unless children.empty?
        stream << self.render(Context.new({@collection_id => children, :level => (level + 1)}), [])
      end
      @enditem.render(context, stream)
    end
  end
  @end.render(context, stream)
end