rails--rails/actionpack/lib/action_view/template/template.rb

82 lines
2.3 KiB
Ruby
Raw Normal View History

# encoding: utf-8
# This is so that templates compiled in this file are UTF-8
2009-04-22 23:41:06 +00:00
require 'set'
2009-04-15 00:22:51 +00:00
require "action_view/template/path"
module ActionView
class Template
extend TemplateHandlers
attr_reader :source, :identifier, :handler, :mime_type, :details
2009-04-15 00:22:51 +00:00
def initialize(source, identifier, handler, details)
@source = source
@identifier = identifier
@handler = handler
@details = details
format = details.delete(:format) || begin
# TODO: Clean this up
handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html"
end
@mime_type = Mime::Type.lookup_by_extension(format.to_s)
@details[:formats] = Array.wrap(format && format.to_sym)
2009-04-15 00:22:51 +00:00
end
def render(view, locals, &blk)
method_name = compile(locals, view)
view.send(method_name, locals, &blk)
end
# TODO: Figure out how to abstract this
def variable_name
identifier[%r'_?(\w+)(\.\w+)*$', 1].to_sym
end
# TODO: Figure out how to abstract this
def counter_name
"#{variable_name}_counter".to_sym
end
# TODO: kill hax
def partial?
@details[:partial]
end
private
def compile(locals, view)
method_name = build_method_name(locals)
return method_name if view.respond_to?(method_name)
locals_code = locals.keys.map! { |key| "#{key} = local_assigns[:#{key}];" }.join
source = <<-end_src
def #{method_name}(local_assigns)
old_output_buffer = output_buffer;#{locals_code};#{@handler.call(self)}
ensure
self.output_buffer = old_output_buffer
end
end_src
begin
ActionView::Base::CompiledTemplates.module_eval(source, identifier, 0)
method_name
rescue Exception => e # errors from template code
if logger = (view && view.logger)
logger.debug "ERROR: compiling #{method_name} RAISED #{e}"
logger.debug "Function body: #{source}"
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
end
raise ActionView::TemplateError.new(self, {}, e)
end
end
def build_method_name(locals)
# TODO: is locals.keys.hash reliably the same?
"_render_template_#{@identifier.hash}_#{__id__}_#{locals.keys.hash}".gsub('-', "_")
end
end
end