lib/roda/plugins/render.rb in roda-1.3.0 vs lib/roda/plugins/render.rb in roda-2.0.0

- old
+ new

@@ -26,11 +26,11 @@ # # :cache :: nil/false to not cache templates (useful for development), defaults # to true unless RACK_ENV is development to automatically use the # default template cache. # :engine :: The tilt engine to use for rendering, defaults to 'erb'. - # :escape :: Use Roda's Erubis escaping support, which makes <%= %> escape output, + # :escape :: Use Roda's Erubis escaping support, which makes <tt><%= %></tt> escape output, # <tt><%== %></tt> not escape output, and handles postfix conditions inside # <tt><%= %></tt> tags. # :ext :: The file extension to assume for view files, defaults to the :engine # option. # :layout :: The base name of the layout file, defaults to 'layout'. @@ -63,19 +63,20 @@ # pass a single options hash to the render/view method, while # still allowing you to specify the template name. # :template_block :: Pass this block when creating the underlying template, # ignored when using :inline. # :template_class :: Provides the template class to use, inside of using - # Tilt or a Tilt[:engine]. + # Tilt or <tt>Tilt[:engine]</tt>. # # Here's how those options are used: # # view(:inline=>'<%= @foo %>') # render(:path=>'/path/to/template.erb') # # If you pass a hash as the first argument to +view+ or +render+, it should - # have either +:inline+ or +:path+ as one of the keys. + # have either +:template+, +:inline+, +:path+, or +:content+ (for +view+) as + # one of the keys. module Render OPTS={}.freeze def self.load_dependencies(app, opts=OPTS) if opts[:escape] @@ -83,31 +84,34 @@ end end # Setup default rendering options. See Render for details. def self.configure(app, opts=OPTS) + orig_opts = opts if app.opts[:render] app.opts[:render] = app.opts[:render].merge(opts) else app.opts[:render] = opts.dup end - if opts[:opts] && !opts[:template_opts] - RodaPlugins.deprecate("The render plugin :opts option is deprecated and will be removed in Roda 2. Switch to using the :template_opts option") - app.opts[:render][:template_opts] = opts[:opts] - end - opts = app.opts[:render] opts[:engine] ||= "erb" opts[:ext] = nil unless opts.has_key?(:ext) opts[:views] ||= File.expand_path("views", Dir.pwd) - opts[:layout] = "layout" unless opts.has_key?(:layout) - opts[:layout_opts] ||= (opts[:layout_opts] || {}).dup + opts[:layout_opts] = (opts[:layout_opts] || {}).dup - if layout = opts[:layout] - layout = {:template=>layout} unless layout.is_a?(Hash) - opts[:layout_opts] = opts[:layout_opts].merge(layout) + if layout = orig_opts.fetch(:layout, true) + opts[:layout] = true unless opts.has_key?(:layout) + + case layout + when Hash + opts[:layout_opts].merge!(layout) + when true + opts[:layout_opts][:template] ||= 'layout' + else + opts[:layout_opts][:template] = layout + end end template_opts = opts[:template_opts] = (opts[:template_opts] || {}).dup template_opts[:outvar] ||= '@_out_buf' if RUBY_VERSION >= "1.9" && !template_opts.has_key?(:default_encoding) @@ -115,26 +119,24 @@ end if opts[:escape] template_opts[:engine_class] = ErubisEscaping::Eruby end opts[:cache] = app.thread_safe_cache if opts.fetch(:cache, ENV['RACK_ENV'] != 'development') - opts.extend(RodaDeprecateMutation) - opts[:layout_opts].extend(RodaDeprecateMutation) - opts[:template_opts].extend(RodaDeprecateMutation) + opts[:layout_opts].freeze + opts[:template_opts].freeze + opts.freeze end module ClassMethods # Copy the rendering options into the subclass, duping # them as necessary to prevent changes in the subclass # affecting the parent class. def inherited(subclass) super - opts = subclass.opts[:render].dup - opts[:layout_opts] = opts[:layout_opts].dup.extend(RodaDeprecateMutation) - opts[:template_opts] = opts[:template_opts].dup.extend(RodaDeprecateMutation) + opts = subclass.opts[:render] = subclass.opts[:render].dup opts[:cache] = thread_safe_cache if opts[:cache] - subclass.opts[:render] = opts.extend(RodaDeprecateMutation) + opts.freeze end # Return the render options for this class. def render_opts opts[:render] @@ -146,14 +148,10 @@ def render(template, opts = OPTS, &block) opts = find_template(parse_template_opts(template, opts)) cached_template(opts) do template_opts = render_opts[:template_opts] current_template_opts = opts[:template_opts] - if opts[:opts] && !current_template_opts - RodaPlugins.deprecate("The render method :opts option is deprecated and will be removed in Roda 2. Switch to using the :template_opts option") - current_template_opts = opts[:opts] - end template_opts = template_opts.merge(current_template_opts) if current_template_opts opts[:template_class].new(opts[:path], 1, template_opts, &opts[:template_block]) end.render(self, (opts[:locals]||OPTS), &block) end @@ -167,26 +165,25 @@ # Render the given template. If there is a default layout # for the class, take the result of the template rendering # and render it inside the layout. See Render for details. def view(template, opts=OPTS) opts = parse_template_opts(template, opts) - content = opts[:content] || render(opts) + content = opts[:content] || render_template(opts) - if layout = opts.fetch(:layout, (OPTS if render_opts[:layout])) - layout_opts = render_opts[:layout_opts] - if opts[:layout_opts] - layout_opts = opts[:layout_opts].merge(layout_opts) - end - - content = render(layout, layout_opts){content} + if layout_opts = view_layout_opts(opts) + content = render_template(layout_opts){content} end content end private + # Private alias for render. Should be used by other plugins when they want to render a template + # without a layout, as plugins can override render to use a layout. + alias render_template render + # If caching templates, attempt to retrieve the template from the cache. Otherwise, just yield # to get the template. def cached_template(opts, &block) if cache = render_opts[:cache] key = opts[:key] @@ -212,14 +209,10 @@ opts[:template_class] ||= ::Tilt end if render_opts[:cache] template_opts = opts[:template_opts] - if opts[:opts] && !template_opts - RodaPlugins.deprecate("The render method :opts option is deprecated and will be removed in Roda 2. Switch to using the :template_opts option") - template_opts = opts[:opts] - end template_block = opts[:template_block] if !content key = if template_class || template_opts || template_block [path, template_class, template_opts, template_block] else @@ -240,14 +233,39 @@ # The name to use for the template. By default, just converts the :template option to a string. def template_name(opts) opts[:template].to_s end - # The path for the given template. + # The template path for the given options. def template_path(opts) render_opts = render_opts() "#{opts[:views] || render_opts[:views]}/#{template_name(opts)}.#{opts[:ext] || render_opts[:ext] || render_opts[:engine]}" end + + # 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 = if opts[:layout_opts] + opts[:layout_opts].merge(render_opts[:layout_opts]) + else + render_opts[:layout_opts].dup + end + + case layout + when Hash + layout_opts.merge!(layout) + when true + # use default layout + else + layout_opts[:template] = layout + end + + layout_opts + end + end + end end register_plugin(:render, Render) end