module Padrino::Rendering::InstanceMethods

def content_type(type=nil, params={}) #:nodoc:

:nodoc:
def content_type(type=nil, params={}) #:nodoc:
  type.nil? ? @_content_type : super(type, params)
end

def locale


Return the I18n.locale if I18n is defined
#
def locale
  I18n.locale if defined?(I18n)
end

def render(engine, data=nil, options={}, locals={}, &block)


* Use render { :a => 1, :b => 2, :c => 3 } # => return a json string
* Use render 'path/to/template', :layout => false, :engine => 'haml'
* Use render 'path/to/template', :layout => false
* Use render 'path/to/template.haml' (with explicit engine lookup)
* Use render 'path/to/my/template' (with engine lookup)
* Use render 'path/to/my/template' (without symbols)
* Using layout similar to rails

Enhancing Sinatra render functionality for:
#
def render(engine, data=nil, options={}, locals={}, &block)
  # If engine is a hash then render data converted to json
  return engine.to_json if engine.is_a?(Hash)
  # If engine is nil, ignore engine parameter and shift up all arguments
  # render nil, "index", { :layout => true }, { :localvar => "foo" }
  engine, data, options = data, options, locals if engine.nil? && data
  # Data is a hash of options when no engine isn't explicit
  # render "index", { :layout => true }, { :localvar => "foo" }
  # Data is options, and options is locals in this case
  data, options, locals = nil, data, options if data.is_a?(Hash)
  # If data is unassigned then this is a likely a template to be resolved
  # This means that no engine was explicitly defined
  data, engine = *resolve_template(engine, options) if data.nil?
  # Setup root
  root = settings.respond_to?(:root) ? settings.root : ""
  # Use @layout if it exists
  options[:layout] = @layout if options[:layout].nil?
  # Resolve layouts similar to in Rails
  if (options[:layout].nil? || options[:layout] == true) && !settings.templates.has_key?(:layout)
    layout_path, layout_engine = *resolved_layout
    options[:layout] = layout_path || false # We need to force layout false so sinatra don't try to render it
    options[:layout] = false unless layout_engine == engine # TODO allow different layout engine
    options[:layout_engine] = layout_engine || engine if options[:layout]
    logger.debug "Resolving layout #{root}/views#{options[:layout]}" if defined?(logger) && options[:layout].present?
  elsif options[:layout].present?
    options[:layout] = settings.fetch_layout_path(options[:layout] || @layout)
    logger.debug "Resolving layout #{root}/views#{options[:layout]}" if defined?(logger)
  end
  # Cleanup the template
  @current_engine, engine_was = engine, @current_engine
  @_out_buf,  _buf_was = "", @_out_buf
  # Pass arguments to Sinatra render method
  super(engine, data, options.dup, locals, &block)
ensure
  @current_engine = engine_was
  @_out_buf = _buf_was
end

def resolve_template(template_path, options={})


# If you request "/foo" with I18n.locale == :de => [:"/path/to/foo.de.haml", :haml]
# If you request "/foo.js" with I18n.locale == :ru => [:"/path/to/foo.ru.js", :erb]
get "/foo", :provides => [:html, :js] do; render 'path/to/foo'; end

==== Example

:raise_exceptions:: Raises a +TemplateNotFound+ exception if the template cannot be located.
:strict_format:: The resolved template must match the content_type of the request (defaults to false)

=== Options

Returns the template path and engine that match content_type (if present), I18n.locale.
#
def resolve_template(template_path, options={})
  # Fetch cached template for rendering options
  template_path = "/#{template_path}" unless template_path.to_s[0] == ?/
  rendering_options = [template_path, content_type, locale]
  cached_template = settings.fetch_template_file(rendering_options)
  return cached_template if cached_template
  # Resolve view path and options
  options.reverse_merge!(DEFAULT_RENDERING_OPTIONS)
  view_path = options.delete(:views) || settings.views || "./views"
  target_extension = File.extname(template_path)[1..-1] || "none" # explicit template extension
  template_path = template_path.chomp(".#{target_extension}")
  # Generate potential template candidates
  templates = Dir[File.join(view_path, template_path) + ".*"].map do |file|
    template_engine = File.extname(file)[1..-1].to_sym # retrieves engine extension
    template_file   = file.sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
    [template_file, template_engine] unless IGNORE_FILE_PATTERN.any? { |pattern| template_engine.to_s =~ pattern }
  end
  # Check if we have a simple content type
  simple_content_type = [:html, :plain].include?(content_type)
  # Resolve final template to render
  located_template =
    templates.find { |file, e| file.to_s == "#{template_path}.#{locale}.#{content_type}" } ||
    templates.find { |file, e| file.to_s == "#{template_path}.#{locale}" && simple_content_type } ||
    templates.find { |file, e| File.extname(file.to_s) == ".#{target_extension}" or e.to_s == target_extension.to_s } ||
    templates.find { |file, e| file.to_s == "#{template_path}.#{content_type}" } ||
    templates.find { |file, e| file.to_s == "#{template_path}" && simple_content_type } ||
    (!options[:strict_format] && templates.first) # If not strict, fall back to the first located template
  raise TemplateNotFound, "Template '#{template_path}' not found in '#{view_path}'!"  if !located_template && options[:raise_exceptions]
  settings.cache_template_file!(located_template, rendering_options) unless settings.reload_templates?
  located_template
end

def resolved_layout


=> [nil, nil]
=> ["/layouts/custom", :erb]
resolve_layout

==== Example

Returns the located layout tuple to be used for the rendered template (if available)
#
def resolved_layout
  located_layout = resolve_template(settings.fetch_layout_path, :raise_exceptions => false, :strict_format => true)
  located_layout ? located_layout : [nil, nil]
end