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