lib/roda/plugins/render_locals.rb
# frozen-string-literal: true require_relative 'render' # class Roda module RodaPlugins # The render_locals plugin allows setting default locals for rendering templates. # # plugin :render_locals, render: {heading: 'Hello'} # # route do |r| # r.get "foo" do # view 'foo', locals: {name: 'Foo'} # locals: {:heading=>'Hello', :name=>'Foo'} # end # # r.get "bar" do # view 'foo', locals: {heading: 'Bar'} # locals: {:heading=>'Bar'} # end # # view "default" # locals: {:heading=>'Hello'} # end # # The render_locals plugin accepts the following options: # # render :: The default locals to use for template rendering # layout :: The default locals to use for layout rendering # merge :: Whether to merge template locals into layout locals module RenderLocals def self.load_dependencies(app, opts=OPTS) app.plugin :render end def self.configure(app, opts=OPTS) app.opts[:render_locals] = (app.opts[:render_locals] || {}).merge(opts[:render]||{}).freeze app.opts[:layout_locals] = (app.opts[:layout_locals] || {}).merge(opts[:layout]||{}).freeze if opts.has_key?(:merge) app.opts[:merge_locals] = opts[:merge] app.opts[:layout_locals] = app.opts[:render_locals].merge(app.opts[:layout_locals]).freeze end end module InstanceMethods private if Render::COMPILED_METHOD_SUPPORT # Disable use of cached templates, since it assumes a render/view call with no # options will have no locals. def _cached_template_method(template) nil end def _optimized_view_content(template) nil end end def render_locals opts[:render_locals] end def layout_locals opts[:layout_locals] end # If this isn't the layout template, then use the plugin's render locals as the default locals. def render_template_opts(template, opts) opts = super return opts if opts[:_is_layout] plugin_locals = render_locals if locals = opts[:locals] plugin_locals = Hash[plugin_locals].merge!(locals) end opts[:locals] = plugin_locals opts end # If using a layout, then use the plugin's layout locals as the default locals. def view_layout_opts(opts) if layout_opts = super merge_locals = layout_opts.has_key?(:merge_locals) ? layout_opts[:merge_locals] : self.opts[:merge_locals] locals = {} locals.merge!(layout_locals) if merge_locals && (method_locals = opts[:locals]) locals.merge!(method_locals) end if method_layout_locals = layout_opts[:locals] locals.merge!(method_layout_locals) end layout_opts[:locals] = locals layout_opts end end end end register_plugin(:render_locals, RenderLocals) end end