summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/zorglub/node.rb30
-rw-r--r--spec/node_spec.rb12
-rw-r--r--spec/spec_helper.rb11
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