module Roda::RodaPlugins::Render

  1. lib/roda/plugins/render.rb

The render plugin adds support for template rendering using the tilt library. Two methods are provided for template rendering, view (which uses the layout) and render (which does not).

plugin :render

route do |r|
  r.is 'foo' do
    view('foo') # renders views/foo.erb inside views/layout.erb
  end

  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

The following plugin options are supported:

:allowed_paths

Set the template paths to allow. Attempts to render paths outside of this directory will raise an error. Defaults to the :views directory.

:cache

nil/false to disable template caching by default. By default, caching is disabled by default if RACK_ENV is development.

:cache_class

A class to use as the template cache instead of the default.

:check_paths

Can be set to false to turn off template path checking.

:engine

The tilt engine to use for rendering, also the default file extension for templates, defaults to 'erb'.

:escape

Use Erubi as the ERB template engine, and enable escaping by default, which makes <%= %> escape output and <%== %> not escape output. If given, sets the :escape=>true option for all template engines, which can break some non-ERB template engines. You can use a string or array of strings as the value for this option to only set the :escape=>true option for those specific template engines.

: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.

:template_opts

The tilt options used when rendering all templates. defaults to: {outvar: '@_out_buf', default_encoding: Encoding.default_external}.

: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 application's :root option (the process's working directory by default).

Render/View Method Options

Most of these options can be overridden at runtime by passing options to the view or render methods:

view('foo', engine: 'html.erb')
render('foo', views: 'admin_views')

There are additional options to view and render that are available at runtime:

:cache

Set to false to not cache this template, even when caching is on by default. Set to true to force caching for this template, even when the default is to not cache (e.g. when using the :template_block option).

:cache_key

Explicitly set the hash key to use when caching.

:content

Only respected by view, provides the content to render inside the layout, instead of rendering a template to get the content.

:inline

Use the value given as the template code, instead of looking for template code in a file.

:locals

Hash of local variables to make available inside the template.

:path

Use the value given as the full pathname for the file, instead of using the :views and :engine option in combination with the template name.

:scope

The object in which context to evaluate the template. By default, this is the Roda instance.

:template

Provides the name of the template to use. This allows you 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. Disables caching of the template by default.

:template_class

Provides the template class to use, inside of using Tilt or Tilt[:engine].

Here's an example of using these options:

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 :template, :inline, :path, or :content (for view) as one of the keys.

Speeding Up Template Rendering

By default, determining the cache key to use for the template can be a lot of work. If you specify the :cache_key option, you can save Roda from having to do that work, which will make your application faster. However, if you do this, you need to make sure you choose a correct key.

If your application uses a unique template per path, in that the same path never uses more than one template, you can use the view_options plugin and do:

set_view_options cache_key: r.path_info

at the top of your route block. You can even do this if you do have paths that use more than one template, as long as you specify :cache_key specifically when rendering in those paths.

If you use a single layout in your application, you can also make layout rendering faster by specifying :cache_key inside the :layout_opts plugin option.

Methods

Public Class

  1. configure

Public Class methods

configure (app, opts=OPTS)

Setup default rendering options. See Render for details.

[show source]
    # File lib/roda/plugins/render.rb
140 def self.configure(app, opts=OPTS)
141   if app.opts[:render]
142     orig_cache = app.opts[:render][:cache]
143     opts = app.opts[:render][:orig_opts].merge(opts)
144   end
145   app.opts[:render] = opts.dup
146   app.opts[:render][:orig_opts] = opts
147 
148   opts = app.opts[:render]
149   opts[:engine] = (opts[:engine] || "erb").dup.freeze
150   opts[:views] = app.expand_path(opts[:views]||"views").freeze
151   opts[:allowed_paths] ||= [opts[:views]].freeze
152   opts[:allowed_paths] = opts[:allowed_paths].map{|f| app.expand_path(f, nil)}.uniq.freeze
153   opts[:check_paths] = true unless opts.has_key?(:check_paths)
154 
155   unless opts.has_key?(:explicit_cache)
156     opts[:explicit_cache] = if opts.fetch(:cache, true)
157       ENV['RACK_ENV'] == 'development'
158     else
159       true
160     end
161   end
162 
163   opts[:cache] = orig_cache || (opts[:cache_class] || RodaCache).new
164 
165   opts[:layout_opts] = (opts[:layout_opts] || {}).dup
166   opts[:layout_opts][:_is_layout] = true
167   if opts[:layout_opts][:views]
168     opts[:layout_opts][:views] = app.expand_path(opts[:layout_opts][:views]).freeze
169   end
170 
171   if layout = opts.fetch(:layout, true)
172     opts[:layout] = true
173 
174     case layout
175     when Hash
176       opts[:layout_opts].merge!(layout)
177     when true
178       opts[:layout_opts][:template] ||= 'layout'
179     else
180       opts[:layout_opts][:template] = layout
181     end
182   end
183   opts[:layout_opts].freeze
184 
185   template_opts = opts[:template_opts] = (opts[:template_opts] || {}).dup
186   template_opts[:outvar] ||= '@_out_buf'
187   unless template_opts.has_key?(:default_encoding)
188     template_opts[:default_encoding] = Encoding.default_external
189   end
190 
191   engine_opts = opts[:engine_opts] = (opts[:engine_opts] || {}).dup
192   engine_opts.to_a.each do |k,v|
193     engine_opts[k] = v.dup.freeze
194   end
195 
196   if escape = opts[:escape]
197     require 'tilt/erubi'
198 
199     case escape
200     when String, Array
201       Array(escape).each do |engine|
202         engine_opts[engine] = (engine_opts[engine] || {}).merge(:escape => true).freeze
203       end
204     else
205       template_opts[:escape] = true
206     end
207   end
208 
209   template_opts.freeze
210   engine_opts.freeze
211   opts.freeze
212 end