4 # NOTE: The template that this mixin is being included into is frozen
5 # so you cannot set or modify any instance variables
6 module Renderable
#:nodoc:
7 extend ActiveSupport
::Memoizable
14 Template
.handler_class_for_extension(extension
)
22 def method_name_without_locals
23 ['_run', extension
, method_segment
].compact
.join('_')
25 memoize
:method_name_without_locals
27 def render(view
, local_assigns
= {})
28 compile(local_assigns
)
30 view
.with_template
self do
31 view
.send(:_evaluate_assigns_and_ivars)
32 view
.send(:_set_controller_content_type, mime_type
) if respond_to
?(:mime_type)
34 view
.send(method_name(local_assigns
), local_assigns
) do |*names
|
35 ivar
= :@_proc_for_layout
36 if !view
.instance_variable_defined
?(:"@content_for_#{names.first}") && view
.instance_variable_defined
?(ivar
) && (proc
= view
.instance_variable_get(ivar
))
37 view
.capture(*names
, &proc
)
38 elsif view
.instance_variable_defined
?(ivar
= :"@content_for_#{names.first || :layout}")
39 view
.instance_variable_get(ivar
)
45 def method_name(local_assigns
)
46 if local_assigns
&& local_assigns
.any
?
47 method_name
= method_name_without_locals
.dup
48 method_name
<< "_locals_#{local_assigns.keys.map { |k| k.to_s }.sort.join('_')}"
50 method_name
= method_name_without_locals
56 # Compile and evaluate the template's code (if necessary)
57 def compile(local_assigns
)
58 render_symbol
= method_name(local_assigns
)
60 if !Base
::CompiledTemplates.method_defined
?(render_symbol
) || recompile
?
61 compile
!(render_symbol
, local_assigns
)
65 def compile
!(render_symbol
, local_assigns
)
66 locals_code
= local_assigns
.keys
.map
{ |key
| "#{key} = local_assigns[:#{key}];" }.join
69 def #{render_symbol}(local_assigns)
70 old_output_buffer = output_buffer;#{locals_code};#{compiled_source}
72 self.output_buffer = old_output_buffer
77 ActionView
::Base::CompiledTemplates.module_eval(source
, filename
, 0)
78 rescue Errno
::ENOENT => e
79 raise e
# Missing template file, re-raise for Base to rescue
80 rescue Exception
=> e
# errors from template code
81 if logger
= defined?(ActionController
) && Base
.logger
82 logger
.debug
"ERROR: compiling #{render_symbol} RAISED #{e}"
83 logger
.debug
"Function body: #{source}"
84 logger
.debug
"Backtrace: #{e.backtrace.join("\n")}"
87 raise ActionView
::TemplateError.new(self, {}, e
)