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]) && (cache = render_opts[:cache]) && (key = opts[:cache_key])
    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] ||= opts[:ext]
  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 render_opts[:cache]
    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
  end
  opts
end

def merge_render_locals(opts)

Merge any :locals specified in the render_opts into the :locals option given.
def merge_render_locals(opts)
  if !opts[:_is_layout] && (r_locals = render_opts[:locals])
    opts[:locals] = if locals = opts[:locals]
      Hash[r_locals].merge!(locals)
    else
      r_locals
    end
  end
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 = parse_template_opts(template, opts)
  merge_render_locals(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

so you should not attempt to modify it.
is not currently frozen, it may be frozen in a future version,
Return the render options for the instance's class. While this
def render_opts
  self.class.render_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: #{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
    merge_locals = layout_opts[:merge_locals]
    if method_layout_opts = opts[:layout_opts]
      method_layout_locals = method_layout_opts[:locals]
      merge_locals = method_layout_opts[:merge_locals] if method_layout_opts.has_key?(:merge_locals)
    end
    locals = {}
    if merge_locals && (plugin_locals = render_opts[:locals])
      locals.merge!(plugin_locals)
    end
    if layout_locals = layout_opts[:locals]
      locals.merge!(layout_locals)
    end
    if merge_locals && (method_locals = opts[:locals])
      locals.merge!(method_locals)
    end
    if method_layout_locals
      locals.merge!(method_layout_locals)
    end
    layout_opts.merge!(method_layout_opts) if method_layout_opts
    layout_opts[:locals] = locals unless locals.empty?
    case layout
    when Hash
      layout_opts.merge!(layout)
    when true
      # use default layout
    else
      layout_opts[:template] = layout
    end
    layout_opts
  end
end