h2o 0.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +11 -0
- data/.gitignore +1 -0
- data/.project +17 -0
- data/README.md +0 -0
- data/Rakefile +32 -0
- data/TODO.md +5 -0
- data/VERSION +1 -0
- data/benchmark/parser.rb +57 -0
- data/benchmark/source.html +4212 -0
- data/example/h2o/base.html +0 -1
- data/example/h2o/index.html +10 -0
- data/example/h2o/layout.html +11 -0
- data/example/request.html +0 -0
- data/example/server +1 -1
- data/h2o.gemspec +101 -41
- data/init.rb +1 -0
- data/lib/.DS_Store +0 -0
- data/lib/core_ext/object.rb +0 -0
- data/lib/h2o.rb +29 -39
- data/lib/h2o/constants.rb +2 -2
- data/lib/h2o/context.rb +3 -10
- data/lib/h2o/error.rb +9 -0
- data/lib/h2o/filters/default.rb +0 -0
- data/lib/h2o/nodes.rb +5 -1
- data/lib/h2o/tags.rb +1 -6
- data/lib/h2o/tags/block.rb +0 -30
- data/lib/h2o/tags/extends.rb +33 -0
- data/lib/h2o/tags/for.rb +7 -6
- data/lib/h2o/tags/with.rb +0 -0
- data/lib/h2o/template.rb +33 -0
- data/spec/fixtures/_partial.html +0 -0
- data/spec/fixtures/a.html +1 -0
- data/spec/fixtures/b.html +0 -0
- data/spec/fixtures/deep/folder/c.html +0 -0
- data/spec/h2o/context_spec.rb +134 -0
- data/spec/h2o/default.html +93 -0
- data/spec/h2o/file_loader_spec.rb +35 -0
- data/spec/h2o/filters_spec.rb +57 -0
- data/spec/h2o/parser_spec.rb +78 -0
- data/spec/h2o/tags/block_spec.rb +26 -0
- data/spec/h2o/tags/for_spec.rb +65 -0
- data/spec/h2o/tags/if_spec.rb +58 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +24 -0
- metadata +81 -27
- data/lib/h2o/errors.rb +0 -7
- data/lib/h2o/tags/recurse.rb +0 -55
| @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe H2o::Tags::For do
         | 
| 4 | 
            +
              describe "Iterations" do  
         | 
| 5 | 
            +
                it "should iteration through array" do
         | 
| 6 | 
            +
                  t = parse("{% for a in list %}{{ a }}{% endfor %}")
         | 
| 7 | 
            +
                  t.render(:list => [1,2,3]).should == '123'
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
                it "should iterate through array subclass" do
         | 
| 11 | 
            +
                  t = parse("{% for i, user in users %}{{ i }}.{{ user }}{% endfor %}")
         | 
| 12 | 
            +
                  t.render(:users =>%w(PeterIT ManHoodHero)).should == '0.PeterIT1.ManHoodHero'
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                it "should iterate through a hash object" do
         | 
| 16 | 
            +
                  person = {:name => 'taylor', :age => 19 }
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                  t = parse("{% for a in person %}{{ a }}{% endfor %}")
         | 
| 19 | 
            +
                  t.render(:person => person).should == 'taylor19'
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  t = parse("{%for a, b in person %}{{ a }}{{ b }}{% endfor %}")
         | 
| 22 | 
            +
                  t.render(:person => person).should == 'nametaylorage19'
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              describe "Magic loop variable" do
         | 
| 27 | 
            +
                before do
         | 
| 28 | 
            +
                  @context = {:words=> %w(something else about this person) }
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                it "should correct iteration counters" do
         | 
| 32 | 
            +
                  fortag('{{ loop.counter }}').render(@context).should == '12345'
         | 
| 33 | 
            +
                  fortag('{{ loop.counter0 }}').render(@context).should == '01234'
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  fortag('{{ loop.revcounter }}').render(@context).should == '54321'
         | 
| 36 | 
            +
                  fortag('{{ loop.revcounter0 }}').render(@context).should == '43210'
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                it "should have .even and .odd iteration flag" do
         | 
| 40 | 
            +
                  fortag('{% if loop.even %}{{ item }}{% endif %}').render(@context).should == 'elsethis'
         | 
| 41 | 
            +
                  fortag('{% if loop.odd %}{{ item}}{% endif %}').render(@context).should == 'somethingaboutperson'
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it "should have .first and .last flag to indicate if it's first/last iteration" do
         | 
| 45 | 
            +
                  fortag('{%if loop.first %}{{ item }}{% endif }').render(@context).should == 'something'
         | 
| 46 | 
            +
                  fortag('{%if loop.last %}{{ item }}{% endif }').render(@context).should == 'person'
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                it "should have parent property pointer to parent loop" do
         | 
| 50 | 
            +
                  template = fortag '{% for num in numbers %}{{ loop.parent.counter }}-{{ item }}{% endfor %}'
         | 
| 51 | 
            +
                  expect = '1-something1-something2-else2-else3-about3-about4-this4-this5-person5-person'
         | 
| 52 | 
            +
                  
         | 
| 53 | 
            +
                  template.render(@context.merge(:numbers=> [6,8])).should == expect
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                  template = fortag '{% for num in numbers %}{% if loop.parent.first %}{{ num }}-{{ item }}{% endif %}{% endfor %}'
         | 
| 56 | 
            +
                  expect = '88-something99-something66-something'
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  template.render(@context.merge(:numbers=> [88,99,66])).should == expect
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                def fortag(body)
         | 
| 62 | 
            +
                  parse("{% for item in words %}#{body}{% endfor %}")
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe H2o::Tags::If do
         | 
| 4 | 
            +
              it "should render if body when expression evaluated as true" do
         | 
| 5 | 
            +
                parse('{% if true %}if body{% endif %}').render.should == 'if body'    
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
              
         | 
| 8 | 
            +
              it "should render else body when expression yields false" do
         | 
| 9 | 
            +
                parse('{% if !true %}{% else %}else body{% endif %}').render.should == 'else body'
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              describe "Basic type comparisons" do
         | 
| 13 | 
            +
                it "should compare numbers" do
         | 
| 14 | 
            +
                  parse('{% if 3 > 2 %}Yes{% endif %}').render.should == 'Yes'
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
                
         | 
| 17 | 
            +
                it "should compare string" do
         | 
| 18 | 
            +
                  parse('{% if "z" > "a" %}Y{% endif %}').render.should == 'Y'
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                
         | 
| 21 | 
            +
                it "should compare variables" do
         | 
| 22 | 
            +
                  parse('{% if a >= b %}Y{% endif %}').render(:a=>2, :b=>1).should == 'Y'
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
              
         | 
| 26 | 
            +
              describe "logical comparisons" do
         | 
| 27 | 
            +
                it "should perform left > right comparison" do
         | 
| 28 | 
            +
                  parse('{% if 3 > 2 %}Yes{% endif %}').render.should == 'Yes'
         | 
| 29 | 
            +
                  
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
                it "should perform left >= right comparison" do
         | 
| 33 | 
            +
                  parse('{% if 3 >= 2 %}Y{% endif %}').render.should == 'Y'
         | 
| 34 | 
            +
                  
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                it "should perform left >= right comparison" do
         | 
| 38 | 
            +
                  parse('{% if 3 >= 2 %}Y{% endif %}').render.should == 'Y'
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
              
         | 
| 42 | 
            +
              describe "Binary logics" do
         | 
| 43 | 
            +
                it "should evaluate a true expression" do
         | 
| 44 | 
            +
                  parse('{% if true %}truth{% endif %}').render.should == 'truth'
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
                
         | 
| 47 | 
            +
                
         | 
| 48 | 
            +
                it "should negate a expression with not or !" do
         | 
| 49 | 
            +
                  parse('{% if not false %}truth{% endif %}').render.should == 'truth'
         | 
| 50 | 
            +
                  
         | 
| 51 | 
            +
                  parse('{% if !false %}truth{% endif %}').render.should == 'truth'
         | 
| 52 | 
            +
                  
         | 
| 53 | 
            +
                  parse('{% if !page.editable %}Locked{% else %}Editable{% endif %}').render(:page=>{:editable => true}).should == 'Editable'
         | 
| 54 | 
            +
                  
         | 
| 55 | 
            +
                  parse('{% if ! 2 > 3 %}Y{% endif %}').render.should == 'Y'
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
    
        data/spec/spec.opts
    ADDED
    
    
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,24 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            $: << File.join(File.dirname(__FILE__), "../lib")
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'h2o'
         | 
| 5 | 
            +
            require 'pp'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            def parse(source)
         | 
| 8 | 
            +
              H2o::Template.parse(source)
         | 
| 9 | 
            +
            end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            class H2o::HashLoader
         | 
| 12 | 
            +
              def initialize(stack)
         | 
| 13 | 
            +
                @stack = stack
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              def read(file)
         | 
| 17 | 
            +
                raise "Template not find" unless exist?(file)
         | 
| 18 | 
            +
                @stack[file]
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
              def exist?(file)
         | 
| 22 | 
            +
                @stack.has_key?(file)
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,20 +1,37 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: h2o
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
               | 
| 4 | 
            +
              prerelease: false
         | 
| 5 | 
            +
              segments: 
         | 
| 6 | 
            +
              - 0
         | 
| 7 | 
            +
              - 3
         | 
| 8 | 
            +
              - 0
         | 
| 9 | 
            +
              version: 0.3.0
         | 
| 5 10 | 
             
            platform: ruby
         | 
| 6 11 | 
             
            authors: 
         | 
| 7 | 
            -
            - Taylor  | 
| 12 | 
            +
            - Taylor luk
         | 
| 8 13 | 
             
            autorequire: 
         | 
| 9 14 | 
             
            bindir: bin
         | 
| 10 15 | 
             
            cert_chain: []
         | 
| 11 16 |  | 
| 12 | 
            -
            date:  | 
| 17 | 
            +
            date: 2010-08-30 00:00:00 +10:00
         | 
| 13 18 | 
             
            default_executable: 
         | 
| 14 | 
            -
            dependencies:  | 
| 15 | 
            -
             | 
| 19 | 
            +
            dependencies: 
         | 
| 20 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 21 | 
            +
              name: schacon-git
         | 
| 22 | 
            +
              prerelease: false
         | 
| 23 | 
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 24 | 
            +
                none: false
         | 
| 25 | 
            +
                requirements: 
         | 
| 26 | 
            +
                - - ">="
         | 
| 27 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 28 | 
            +
                    segments: 
         | 
| 29 | 
            +
                    - 0
         | 
| 30 | 
            +
                    version: "0"
         | 
| 31 | 
            +
              type: :runtime
         | 
| 32 | 
            +
              version_requirements: *id001
         | 
| 16 33 | 
             
            description: h2o is a django inspired template that offers natural template syntax and easy to integrate.
         | 
| 17 | 
            -
            email:  | 
| 34 | 
            +
            email: subjective@gmail.com
         | 
| 18 35 | 
             
            executables: []
         | 
| 19 36 |  | 
| 20 37 | 
             
            extensions: []
         | 
| @@ -22,61 +39,98 @@ extensions: [] | |
| 22 39 | 
             
            extra_rdoc_files: 
         | 
| 23 40 | 
             
            - README.md
         | 
| 24 41 | 
             
            files: 
         | 
| 42 | 
            +
            - .autotest
         | 
| 43 | 
            +
            - .gitignore
         | 
| 44 | 
            +
            - .project
         | 
| 25 45 | 
             
            - README.md
         | 
| 46 | 
            +
            - Rakefile
         | 
| 47 | 
            +
            - TODO.md
         | 
| 48 | 
            +
            - VERSION
         | 
| 49 | 
            +
            - benchmark/parser.rb
         | 
| 50 | 
            +
            - benchmark/source.html
         | 
| 51 | 
            +
            - example/erb/base.html
         | 
| 52 | 
            +
            - example/h2o/base.html
         | 
| 53 | 
            +
            - example/h2o/index.html
         | 
| 54 | 
            +
            - example/h2o/inherit.html
         | 
| 55 | 
            +
            - example/h2o/layout.html
         | 
| 56 | 
            +
            - example/liquid/base.html
         | 
| 57 | 
            +
            - example/request.html
         | 
| 58 | 
            +
            - example/run.rb
         | 
| 59 | 
            +
            - example/server
         | 
| 60 | 
            +
            - example/server.bat
         | 
| 61 | 
            +
            - example/server.rb
         | 
| 26 62 | 
             
            - h2o.gemspec
         | 
| 63 | 
            +
            - init.rb
         | 
| 64 | 
            +
            - lib/.DS_Store
         | 
| 65 | 
            +
            - lib/core_ext/object.rb
         | 
| 27 66 | 
             
            - lib/h2o.rb
         | 
| 28 67 | 
             
            - lib/h2o/constants.rb
         | 
| 29 68 | 
             
            - lib/h2o/context.rb
         | 
| 30 69 | 
             
            - lib/h2o/datatype.rb
         | 
| 31 | 
            -
            - lib/h2o/ | 
| 70 | 
            +
            - lib/h2o/error.rb
         | 
| 32 71 | 
             
            - lib/h2o/filters.rb
         | 
| 33 72 | 
             
            - lib/h2o/filters/default.rb
         | 
| 34 73 | 
             
            - lib/h2o/nodes.rb
         | 
| 35 74 | 
             
            - lib/h2o/parser.rb
         | 
| 36 75 | 
             
            - lib/h2o/tags.rb
         | 
| 37 76 | 
             
            - lib/h2o/tags/block.rb
         | 
| 77 | 
            +
            - lib/h2o/tags/extends.rb
         | 
| 38 78 | 
             
            - lib/h2o/tags/for.rb
         | 
| 39 79 | 
             
            - lib/h2o/tags/if.rb
         | 
| 40 80 | 
             
            - lib/h2o/tags/with.rb
         | 
| 41 | 
            -
            - lib/h2o/ | 
| 42 | 
            -
            -  | 
| 43 | 
            -
            -  | 
| 44 | 
            -
            -  | 
| 45 | 
            -
            -  | 
| 46 | 
            -
            -  | 
| 47 | 
            -
            -  | 
| 48 | 
            -
            -  | 
| 49 | 
            -
            -  | 
| 50 | 
            -
            -  | 
| 51 | 
            -
            -  | 
| 81 | 
            +
            - lib/h2o/template.rb
         | 
| 82 | 
            +
            - spec/fixtures/_partial.html
         | 
| 83 | 
            +
            - spec/fixtures/a.html
         | 
| 84 | 
            +
            - spec/fixtures/b.html
         | 
| 85 | 
            +
            - spec/fixtures/deep/folder/c.html
         | 
| 86 | 
            +
            - spec/h2o/context_spec.rb
         | 
| 87 | 
            +
            - spec/h2o/default.html
         | 
| 88 | 
            +
            - spec/h2o/file_loader_spec.rb
         | 
| 89 | 
            +
            - spec/h2o/filters_spec.rb
         | 
| 90 | 
            +
            - spec/h2o/parser_spec.rb
         | 
| 91 | 
            +
            - spec/h2o/tags/block_spec.rb
         | 
| 92 | 
            +
            - spec/h2o/tags/for_spec.rb
         | 
| 93 | 
            +
            - spec/h2o/tags/if_spec.rb
         | 
| 94 | 
            +
            - spec/spec.opts
         | 
| 95 | 
            +
            - spec/spec_helper.rb
         | 
| 52 96 | 
             
            has_rdoc: true
         | 
| 53 | 
            -
            homepage: http:// | 
| 97 | 
            +
            homepage: http://www.h2o-template.org
         | 
| 54 98 | 
             
            licenses: []
         | 
| 55 99 |  | 
| 56 100 | 
             
            post_install_message: 
         | 
| 57 101 | 
             
            rdoc_options: 
         | 
| 58 | 
            -
            - -- | 
| 59 | 
            -
            - README.md
         | 
| 102 | 
            +
            - --charset=UTF-8
         | 
| 60 103 | 
             
            require_paths: 
         | 
| 61 104 | 
             
            - lib
         | 
| 62 105 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 106 | 
            +
              none: false
         | 
| 63 107 | 
             
              requirements: 
         | 
| 64 108 | 
             
              - - ">="
         | 
| 65 109 | 
             
                - !ruby/object:Gem::Version 
         | 
| 110 | 
            +
                  segments: 
         | 
| 111 | 
            +
                  - 0
         | 
| 66 112 | 
             
                  version: "0"
         | 
| 67 | 
            -
              version: 
         | 
| 68 113 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 114 | 
            +
              none: false
         | 
| 69 115 | 
             
              requirements: 
         | 
| 70 116 | 
             
              - - ">="
         | 
| 71 117 | 
             
                - !ruby/object:Gem::Version 
         | 
| 118 | 
            +
                  segments: 
         | 
| 119 | 
            +
                  - 0
         | 
| 72 120 | 
             
                  version: "0"
         | 
| 73 | 
            -
              version: 
         | 
| 74 121 | 
             
            requirements: []
         | 
| 75 122 |  | 
| 76 123 | 
             
            rubyforge_project: 
         | 
| 77 | 
            -
            rubygems_version: 1.3. | 
| 124 | 
            +
            rubygems_version: 1.3.7
         | 
| 78 125 | 
             
            signing_key: 
         | 
| 79 126 | 
             
            specification_version: 3
         | 
| 80 | 
            -
            summary:  | 
| 81 | 
            -
            test_files:  | 
| 82 | 
            -
             | 
| 127 | 
            +
            summary: h2o is a django inspired template
         | 
| 128 | 
            +
            test_files: 
         | 
| 129 | 
            +
            - spec/h2o/context_spec.rb
         | 
| 130 | 
            +
            - spec/h2o/file_loader_spec.rb
         | 
| 131 | 
            +
            - spec/h2o/filters_spec.rb
         | 
| 132 | 
            +
            - spec/h2o/parser_spec.rb
         | 
| 133 | 
            +
            - spec/h2o/tags/block_spec.rb
         | 
| 134 | 
            +
            - spec/h2o/tags/for_spec.rb
         | 
| 135 | 
            +
            - spec/h2o/tags/if_spec.rb
         | 
| 136 | 
            +
            - spec/spec_helper.rb
         | 
    
        data/lib/h2o/errors.rb
    DELETED
    
    
    
        data/lib/h2o/tags/recurse.rb
    DELETED
    
    | @@ -1,55 +0,0 @@ | |
| 1 | 
            -
            module H2o
         | 
| 2 | 
            -
              module Tags
         | 
| 3 | 
            -
                # Recurse tag allows rendering of tree structures. The template should look something like this:
         | 
| 4 | 
            -
                # {% recurse all_categories with children as category %}
         | 
| 5 | 
            -
                #   <ul>
         | 
| 6 | 
            -
                #     {% loop %}
         | 
| 7 | 
            -
                #       <li>
         | 
| 8 | 
            -
                #         <h{{ level }}>{{ category.title }}</h{{ level }}>
         | 
| 9 | 
            -
                #         {% children %}
         | 
| 10 | 
            -
                #       </li>
         | 
| 11 | 
            -
                #     {% endloop %}
         | 
| 12 | 
            -
                #   </ul>
         | 
| 13 | 
            -
                # {% endrecurse %}
         | 
| 14 | 
            -
                class Recurse < Tag
         | 
| 15 | 
            -
                  
         | 
| 16 | 
            -
                  Syntax = /(#{H2o::NAME_RE})\s+with\s+(#{H2o::IDENTIFIER_RE})\s+as\s+(#{H2o::IDENTIFIER_RE})/
         | 
| 17 | 
            -
                  
         | 
| 18 | 
            -
                  def initialize(parser, argstring)
         | 
| 19 | 
            -
                    @body    = parser.parse(:loop, :children, :endloop, :endrecurse)
         | 
| 20 | 
            -
                    @child   = parser.parse(:children, :endloop, :endrecurse) if parser.token && parser.token.include?('loop')
         | 
| 21 | 
            -
                    @enditem = parser.parse(:endloop, :endrecurse) if parser.token && parser.token.include?('children')
         | 
| 22 | 
            -
                    @end     = parser.parse(:endrecurse) if parser.token && parser.token.include?('endloop')        
         | 
| 23 | 
            -
                    if argstring =~ Syntax
         | 
| 24 | 
            -
                      @collection_id   = $1.to_sym
         | 
| 25 | 
            -
                      @children_method = $2.to_sym
         | 
| 26 | 
            -
                      @item_id         = $3.to_sym
         | 
| 27 | 
            -
                    else
         | 
| 28 | 
            -
                      raise SyntaxError, "Invalid recurse syntax "
         | 
| 29 | 
            -
                    end
         | 
| 30 | 
            -
                  end
         | 
| 31 | 
            -
                  
         | 
| 32 | 
            -
                  def render(context, stream)
         | 
| 33 | 
            -
                    collection = context.resolve(@collection_id)
         | 
| 34 | 
            -
                    @body.render(context, stream)
         | 
| 35 | 
            -
                    context.stack do
         | 
| 36 | 
            -
                      level = context[:level] || 1
         | 
| 37 | 
            -
                      collection.each do |item|
         | 
| 38 | 
            -
                        context[@item_id] = item
         | 
| 39 | 
            -
                        context[:level] = level
         | 
| 40 | 
            -
                        @child.render(context, stream)
         | 
| 41 | 
            -
                        children = item.respond_to?(@children_method) ? item.send(@children_method) : item[@children_method]
         | 
| 42 | 
            -
                        unless children.empty?
         | 
| 43 | 
            -
                          stream << self.render(Context.new({@collection_id => children, :level => (level + 1)}), [])
         | 
| 44 | 
            -
                        end
         | 
| 45 | 
            -
                        @enditem.render(context, stream)
         | 
| 46 | 
            -
                      end
         | 
| 47 | 
            -
                    end
         | 
| 48 | 
            -
                    @end.render(context, stream)
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
                  
         | 
| 51 | 
            -
                  Tags.register(self, :recurse)
         | 
| 52 | 
            -
                  
         | 
| 53 | 
            -
                end
         | 
| 54 | 
            -
              end
         | 
| 55 | 
            -
            end
         |