module Middleman::CoreExtensions::Rendering::InstanceMethods

def render_template(path, locs={}, opts={}, blocks=[])

Returns:
  • (String) -

Parameters:
  • opts (Hash) --
  • locs (Hash) --
  • path (String) --
def render_template(path, locs={}, opts={}, blocks=[])
  # Detect the remdering engine from the extension
  extension = File.extname(path)
  engine = extension[1..-1].to_sym
  # Store last engine for later (could be inside nested renders)
  @current_engine, engine_was = engine, @current_engine
  # Use a dup of self as a context so that instance variables set within
  # the template don't persist for other templates.
  context = self.dup
  blocks.each do |block|
    context.instance_eval(&block)
  end
  # Store current locs/opts for later
  @current_locs = locs, @current_opts = opts
  # Keep rendering template until we've used up all extensions. This
  # handles cases like `style.css.sass.erb`
  content = nil
  while ::Tilt[path]
    begin
      opts[:template_body] = content if content
      content = render_individual_file(path, locs, opts, context)
      path = File.basename(path, File.extname(path))
    rescue LocalJumpError => e
      raise "Tried to render a layout (calls yield) at #{path} like it was a template. Non-default layouts need to be in #{source}/layouts."
    end
  end
  # Certain output file types don't use layouts
  needs_layout = !%w(.js .json .css .txt).include?(File.extname(path))
  # If we need a layout and have a layout, use it
  if needs_layout && layout_path = fetch_layout(engine, opts)
    content = render_individual_file(layout_path, locs, opts, context) { content }
  end
  # Return result
  content
ensure
  # Pop all the saved variables from earlier as we may be returning to a
  # previous render (layouts, partials, nested layouts).
  @current_engine = engine_was
  @content_blocks = nil
  @current_locs = nil
  @current_opts = nil
end