lib/roda/plugins/render.rb in roda-2.16.0 vs lib/roda/plugins/render.rb in roda-2.17.0
- old
+ new
@@ -18,10 +18,28 @@
# r.is 'bar' do
# render('bar') # renders views/bar.erb
# end
# end
#
+ # The +render+ and +view+ methods just return strings, they do not have
+ # side effects (unless the templates themselves have side effects).
+ # As Roda uses the routing block return value as the body of the response,
+ # in most cases you will call these methods as the last expression in a
+ # routing block # to have the response body be the result of the template
+ # rendering.
+ #
+ # Because +render+ and +view+ just return strings, you can call them inside
+ # templates (i.e. for subtemplates/partials), or multiple times in the
+ # same route and combine the results together:
+ #
+ # route do |r|
+ # r.is 'foo-bars' do
+ # @bars = Bar.where(:foo).map{|b| render(:bar, :locals=>{:bar=>b})}.join
+ # view('foo')
+ # end
+ # end
+ #
# You can provide options to the plugin method:
#
# plugin :render, :engine=>'haml', :views=>'admin_views'
#
# = Plugin Options
@@ -44,13 +62,16 @@
# :escape_safe_classes :: String subclasses that should not be HTML escaped when used in
# <tt><%= %></tt> tags, when :escape is used. Can be an array for multiple classes.
# :escaper :: Object used for escaping output of <tt><%= %></tt>, when :escape is used,
# overriding the default. If given, object should respond to +escape_xml+ with
# a single argument and return an output string.
- # :layout :: The base name of the layout file, defaults to 'layout'.
+ # :layout :: The base name of the layout file, defaults to 'layout'. This can be provided as a hash
+ # with the :template or :inline options.
# :layout_opts :: The options to use when rendering the layout, if different
- # from the default options.
+ # from the default options. To pass local variables to the layout, include a :locals
+ # option inside :layout_opts. To automatically merge the view template locals into
+ # the layout template locals, include a :merge_locals option inside :layout_opts.
# :template_opts :: The tilt options used when rendering all templates. defaults to:
# <tt>{:outvar=>'@_out_buf', :default_encoding=>Encoding.default_external}</tt>.
# :engine_opts :: The tilt options to use per template engine. Keys are
# engine strings, values are hashes of template options.
# :views :: The directory holding the view files, defaults to the 'views' subdirectory of the
@@ -152,10 +173,15 @@
end
end
opts[:layout_opts] = (opts[:layout_opts] || {}).dup
opts[:layout_opts][:_is_layout] = true
+
+ if opts[:layout_opts][:merge_locals] && opts[:locals]
+ opts[:layout_opts][:locals] = opts[:locals].merge(opts[:layout_opts][:locals] || {})
+ end
+
if layout = opts.fetch(:layout, true)
opts[:layout] = true unless opts.has_key?(:layout)
case layout
when Hash
@@ -371,19 +397,34 @@
# If a layout should be used, return a hash of options for
# rendering the layout template. If a layout should not be
# used, return nil.
def view_layout_opts(opts)
if layout = opts.fetch(:layout, render_opts[:layout])
+
layout_opts = render_layout_opts
- if l_opts = opts[:layout_opts]
- if (l_locals = l_opts[:locals]) && (layout_locals = layout_opts[:locals])
- set_locals = Hash[layout_locals].merge!(l_locals)
- end
- layout_opts.merge!(l_opts)
- if set_locals
- layout_opts[:locals] = set_locals
- end
+ merge_locals = layout_opts[:merge_locals]
+
+ if method_layout_opts = opts[:layout_opts]
+ method_layout_locals = method_layout_opts[:locals]
+ merge_locals = method_layout_opts[:merge_locals] if method_layout_opts.has_key?(:merge_locals)
end
+
+ locals = {}
+ if merge_locals && (plugin_locals = render_opts[:locals])
+ locals.merge!(plugin_locals)
+ end
+ if layout_locals = layout_opts[:locals]
+ locals.merge!(layout_locals)
+ end
+ if merge_locals && (method_locals = opts[:locals])
+ locals.merge!(method_locals)
+ end
+ if method_layout_locals
+ locals.merge!(method_layout_locals)
+ end
+
+ layout_opts.merge!(method_layout_opts) if method_layout_opts
+ layout_opts[:locals] = locals unless locals.empty?
case layout
when Hash
layout_opts.merge!(layout)
when true