module Roda::RodaPlugins::Render::InstanceMethods

def cached_template(opts, &block)

to get the template.
If caching templates, attempt to retrieve the template from the cache. Otherwise, just yield
def cached_template(opts, &block)
  if (!render_opts[:explicit_cache] || opts[:cache]) && (key = opts[:cache_key])
    cache = render_opts[:cache]
    unless template = cache[key]
      template = cache[key] = yield
    end
    template
  else
    yield
  end
end

def find_template(opts)

template block, and locals to use for the render in the passed options.
Given the template name and options, set the template class, template path/content,
def find_template(opts)
  render_opts = render_opts()
  engine_override = opts[:engine]
  engine = opts[:engine] ||= render_opts[:engine]
  if content = opts[:inline]
    path = opts[:path] = content
    template_class = opts[:template_class] ||= ::Tilt[engine]
    opts[:template_block] = Proc.new{content}
  else
    opts[:views] ||= render_opts[:views]
    path = opts[:path] ||= template_path(opts)
    template_class = opts[:template_class]
    opts[:template_class] ||= ::Tilt
  end
  if (cache = opts[:cache]).nil?
    cache = content || !opts[:template_block]
  end
  if cache
    template_block = opts[:template_block] unless content
    template_opts = opts[:template_opts]
    opts[:cache_key] ||= if template_class || engine_override || template_opts || template_block
      [path, template_class, engine_override, template_opts, template_block]
    else
      path
    end
  else
    opts.delete(:cache_key)
  end
  opts
end

def parse_template_opts(template, opts)

Return a single hash combining the template and opts arguments.
def parse_template_opts(template, opts)
  opts = Hash[opts]
  if template.is_a?(Hash)
    opts.merge!(template)
  else
    opts[:template] = template
    opts
  end
end

def render(template, opts = OPTS, &block)

Render the given template. See Render for details.
def render(template, opts = OPTS, &block)
  opts = render_template_opts(template, opts)
  retrieve_template(opts).render((opts[:scope]||self), (opts[:locals]||OPTS), &block)
end

def render_layout_opts

providing a :layout_opts option to the view/render method.
The default render options to use. These set defaults that can be overridden by
def render_layout_opts
  Hash[render_opts[:layout_opts]]
end

def render_opts

Return the render options for the instance's class.
def render_opts
  self.class.render_opts
end

def render_template_opts(template, opts)

Convert template options to single hash when rendering templates using render.
def render_template_opts(template, opts)
  parse_template_opts(template, opts)
end

def retrieve_template(opts)

Retrieve the Tilt::Template object for the given template and opts.
def retrieve_template(opts)
  unless opts[:cache_key] && opts[:cache] != false
    found_template_opts = opts = find_template(opts)
  end
  cached_template(opts) do
    opts = found_template_opts || find_template(opts)
    template_opts = render_opts[:template_opts]
    if engine_opts = render_opts[:engine_opts][opts[:engine]]
      template_opts = Hash[template_opts].merge!(engine_opts)
    end
    if current_template_opts = opts[:template_opts]
      template_opts = Hash[template_opts].merge!(current_template_opts)
    end
    opts[:template_class].new(opts[:path], 1, template_opts, &opts[:template_block])
  end
end

def template_name(opts)

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

def template_path(opts)

The template path for the given options.
def template_path(opts)
  path = "#{opts[:views]}/#{template_name(opts)}.#{opts[:engine]}"
  if opts.fetch(:check_paths){render_opts[:check_paths]}
    full_path = self.class.expand_path(path)
    unless render_opts[:allowed_paths].any?{|f| full_path.start_with?(f)}
      raise RodaError, "attempt to render path not in allowed_paths: #{full_path} (allowed: #{render_opts[:allowed_paths].join(', ')})"
    end
  end
  path
end

def view(template, opts=OPTS)

and render it inside the layout. See Render for details.
for the class, take the result of the template rendering
Render the given template. If there is a default layout
def view(template, opts=OPTS)
  opts = parse_template_opts(template, opts)
  content = opts[:content] || render_template(opts)
  if layout_opts  = view_layout_opts(opts)
    content = render_template(layout_opts){content}
  end
  content
end

def view_layout_opts(opts)

used, return nil.
rendering the layout template. If a layout should not be
If a layout should be used, return a hash of options for
def view_layout_opts(opts)
  if layout = opts.fetch(:layout, render_opts[:layout])
    layout_opts = render_layout_opts
    method_layout_opts = opts[:layout_opts]
    layout_opts.merge!(method_layout_opts) if method_layout_opts
    case layout
    when Hash
      layout_opts.merge!(layout)
    when true
      # use default layout
    else
      layout_opts[:template] = layout
    end
    layout_opts
  end
end