diff options
| -rw-r--r-- | lib/zorglub/node.rb | 30 | ||||
| -rw-r--r-- | spec/node_spec.rb | 12 | ||||
| -rw-r--r-- | spec/spec_helper.rb | 11 |
3 files changed, 44 insertions, 9 deletions
diff --git a/lib/zorglub/node.rb b/lib/zorglub/node.rb index 1c77438..901e1ec 100644 --- a/lib/zorglub/node.rb +++ b/lib/zorglub/node.rb @@ -146,6 +146,10 @@ module Zorglub File.join map, (args.empty? ? meth : args.map(&:to_s)) end + def partial(meth, *args, **options) + self.class.partial(meth, *args, env: request.env, parent: self, **options) + end + def html %i[map r args engine layout view].inject('') { |s, sym| s + "<p>#{sym} => #{send sym}</p>" } end @@ -236,11 +240,11 @@ module Zorglub node.realize! end - def partial(meth, *args, env: {}, no_hooks: false) - node = new(env, meth.to_s, args, partial: true) + def partial(meth, *args, **options) + node = new(options[:env] || {}, meth.to_s, args, partial: true, **options) return error404 node, meth unless node.respond_to? meth - node.feed!(no_hooks: no_hooks) + node.feed!(no_hooks: options[:no_hooks] || false) node.content end @@ -254,22 +258,30 @@ module Zorglub end end - attr_reader :request, :response, :content, :mime, :state, :engine, :meth, :args + attr_reader :request, :response, :content, :mime, :state, :engine, :meth, :args, :depth, :parent + + def initialize(env, meth, args, **options) + @parent = options[:parent] + @depth = @parent ? @parent.depth + 1 : 0 + raise 'Recursive partial depth limit exceeded' if @depth > 20 - def initialize(env, meth, args, partial: false) @meth = meth @args = args - @partial = partial - @request = Rack::Request.new env - @response = Rack::Response.new + @partial = options[:partial] || false + @request = @parent ? @parent.request : Rack::Request.new(env) + @response = @parent ? @parent.response : Rack::Response.new @cli_vals = {} @debug = app.opt :debug @engine = self.class.engine - @layout = (partial ? nil : self.class.layout) + @layout = (options[:partial] ? nil : self.class.layout) @view = r(meth) @static = self.class.static @cache_lifetime = self.class.cache_lifetime self.class.cli_vals.each { |s, v| cli_val s, *v } + + (options[:locals] || {}).each do |k, v| + instance_variable_set("@#{k}", v) + end end def realize! diff --git a/spec/node_spec.rb b/spec/node_spec.rb index 1612510..3aaec55 100644 --- a/spec/node_spec.rb +++ b/spec/node_spec.rb @@ -192,6 +192,18 @@ describe Zorglub do expect(Node3.after).to eq 0 end + it 'partial with locals should work' do + expect(Node0.partial(:test_locals, locals: { my_local: 'hello' })).to eq 'hello' + end + + it 'recursive partial should work' do + expect(Node0.partial(:test_recursive, 3)).to eq '3-2-1-end' + end + + it 'recursive partial depth limit should be enforced' do + expect { Node0.partial(:test_recursive, 25) }.to raise_error('Recursive partial depth limit exceeded') + end + it 'static pages should be generated' do r = Node6.my_call '/do_static' expect(r[2][0]).to eq 'VAL 1' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a9415df..b81f0cf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -118,6 +118,17 @@ class Node0 < Zorglub::Node engine! :sass end end + + def test_locals + @my_local + end + + def test_recursive(val) + val = val.to_i + return 'end' if val <= 0 + + "#{val}-" + partial(:test_recursive, val - 1) + end end class Node1 < Zorglub::Node |
