From 1dcc59121b9f0c332f6fe93f90fb028ff3448899 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 5 Jul 2008 12:05:50 -0500 Subject: Renamed Renderer to Renderable --- actionpack/lib/action_view/renderable.rb | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 actionpack/lib/action_view/renderable.rb (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb new file mode 100644 index 0000000000..61bd8140fb --- /dev/null +++ b/actionpack/lib/action_view/renderable.rb @@ -0,0 +1,29 @@ +module ActionView + module Renderable + # TODO: Local assigns should not be tied to template instance + attr_accessor :locals + + # TODO: These readers should be private + attr_reader :filename, :source, :handler, :method_key, :method + + def render + prepare! + @handler.render(self) + end + + private + def prepare! + unless @prepared + @view.send(:evaluate_assigns) + @view.current_render_extension = @extension + + if @handler.compilable? + @handler.compile_template(self) # compile the given template, if necessary + @method = @view.method_names[method_key] # Set the method name for this template and run it + end + + @prepared = true + end + end + end +end -- cgit v1.2.3 From 39ba2da82bcc2f9fad494e6ac0a66a3387ab8ee2 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 5 Jul 2008 16:27:43 -0500 Subject: Moved complied method name logic into Renderable --- actionpack/lib/action_view/renderable.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 61bd8140fb..d73dc3e2dc 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -11,6 +11,10 @@ module ActionView @handler.render(self) end + def method_name + ['_run', @extension, method_name_path_segment].compact.join('_').to_sym + end + private def prepare! unless @prepared -- cgit v1.2.3 From 9828aecd2aa98910f17e4b0f52519f4727d198d8 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 5 Jul 2008 23:54:11 -0500 Subject: Lookup compiled methods in CompiledTemplates instance methods set instead of using a "methods_names" hash --- actionpack/lib/action_view/renderable.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index d73dc3e2dc..2e2fff44c6 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -4,15 +4,15 @@ module ActionView attr_accessor :locals # TODO: These readers should be private - attr_reader :filename, :source, :handler, :method_key, :method + attr_reader :filename, :source, :handler def render prepare! @handler.render(self) end - def method_name - ['_run', @extension, method_name_path_segment].compact.join('_').to_sym + def method + ['_run', @extension, @method_segment].compact.join('_').to_sym end private @@ -23,7 +23,6 @@ module ActionView if @handler.compilable? @handler.compile_template(self) # compile the given template, if necessary - @method = @view.method_names[method_key] # Set the method name for this template and run it end @prepared = true -- cgit v1.2.3 From 1d8623b42f6249613d39e834a8742b3b143f2aff Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 6 Jul 2008 01:13:15 -0500 Subject: Added local assign keys to compiled method name so two threads evaluating the same template with different locals don't step on top of each other --- actionpack/lib/action_view/renderable.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 2e2fff44c6..3a30e603fe 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -12,7 +12,7 @@ module ActionView end def method - ['_run', @extension, @method_segment].compact.join('_').to_sym + ['_run', @extension, @method_segment, local_assigns_keys].compact.join('_').to_sym end private @@ -28,5 +28,11 @@ module ActionView @prepared = true end end + + def local_assigns_keys + if @locals && @locals.any? + "locals_#{@locals.keys.map { |k| k.to_s }.sort.join('_')}" + end + end end end -- cgit v1.2.3 From 6ebdd0e32b846e99a9885b06fbca2bed58149c7e Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 11 Jul 2008 15:39:22 -0500 Subject: Changed ActionView::TemplateHandler#render API method signature to render(template, local_assigns = {}) --- actionpack/lib/action_view/renderable.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 3a30e603fe..6a8a0e44fc 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -8,7 +8,7 @@ module ActionView def render prepare! - @handler.render(self) + @handler.render(self, @locals) end def method -- cgit v1.2.3 From 73b34e9f75d33dc0709d4ad36c912bdbb8977994 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sat, 12 Jul 2008 14:33:46 -0500 Subject: Refactor template preloading. New abstractions include Renderable mixins and a refactored Template class. --- actionpack/lib/action_view/renderable.rb | 81 ++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 20 deletions(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 6a8a0e44fc..2c4302146f 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -1,37 +1,78 @@ module ActionView module Renderable - # TODO: Local assigns should not be tied to template instance - attr_accessor :locals + # NOTE: The template that this mixin is beening include into is frozen + # So you can not set or modify any instance variables - # TODO: These readers should be private - attr_reader :filename, :source, :handler + def self.included(base) + @@mutex = Mutex.new + end + + # NOTE: Exception to earlier notice. Ensure this is called before freeze + def handler + @handler ||= Template.handler_class_for_extension(extension) + end - def render - prepare! - @handler.render(self, @locals) + # NOTE: Exception to earlier notice. Ensure this is called before freeze + def compiled_source + @compiled_source ||= handler.new(nil).compile(self) if handler.compilable? end - def method - ['_run', @extension, @method_segment, local_assigns_keys].compact.join('_').to_sym + def render(view, local_assigns = {}) + view.first_render ||= self + view.send(:evaluate_assigns) + view.current_render_extension = extension + compile(local_assigns) if handler.compilable? + handler.new(view).render(self, local_assigns) + end + + def method(local_assigns) + if local_assigns && local_assigns.any? + local_assigns_keys = "locals_#{local_assigns.keys.map { |k| k.to_s }.sort.join('_')}" + end + ['_run', extension, method_segment, local_assigns_keys].compact.join('_').to_sym end private - def prepare! - unless @prepared - @view.send(:evaluate_assigns) - @view.current_render_extension = @extension + # Compile and evaluate the template's code + def compile(local_assigns) + render_symbol = method(local_assigns) - if @handler.compilable? - @handler.compile_template(self) # compile the given template, if necessary - end + @@mutex.synchronize do + return false unless recompile?(render_symbol) + + locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join + + source = <<-end_src + def #{render_symbol}(local_assigns) + old_output_buffer = output_buffer;#{locals_code};#{compiled_source} + ensure + self.output_buffer = old_output_buffer + end + end_src - @prepared = true + begin + file_name = respond_to?(:filename) ? filename : 'compiled-template' + ActionView::Base::CompiledTemplates.module_eval(source, file_name, 0) + rescue Exception => e # errors from template code + if logger = ActionController::Base.logger + logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}" + logger.debug "Function body: #{source}" + logger.debug "Backtrace: #{e.backtrace.join("\n")}" + end + + raise ActionView::TemplateError.new(self, {}, e) + end end end - def local_assigns_keys - if @locals && @locals.any? - "locals_#{@locals.keys.map { |k| k.to_s }.sort.join('_')}" + # Method to check whether template compilation is necessary. + # The template will be compiled if the file has not been compiled yet, or + # if local_assigns has a new key, which isn't supported by the compiled code yet. + def recompile?(symbol) + unless Base::CompiledTemplates.instance_methods.include?(symbol) && Base.cache_template_loading + true + else + false end end end -- cgit v1.2.3 From e0fef66149092dd3d2988fff64f0ce8765735687 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 13 Jul 2008 13:26:48 -0500 Subject: Made ActionView::Base#first_render a little more private. And added _last_render to track the most recent render. Will fix #609 as a side effect. [#609 state:resolved] --- actionpack/lib/action_view/renderable.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 2c4302146f..ebb0f1b674 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -18,9 +18,9 @@ module ActionView end def render(view, local_assigns = {}) - view.first_render ||= self + view._first_render ||= self + view._last_render = self view.send(:evaluate_assigns) - view.current_render_extension = extension compile(local_assigns) if handler.compilable? handler.new(view).render(self, local_assigns) end -- cgit v1.2.3 From 2d6562d51b96af518c1eb2947d6d34d5dd5bad12 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 14 Jul 2008 13:51:59 -0700 Subject: Move dead recompile_template? also --- actionpack/lib/action_view/renderable.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index ebb0f1b674..ffcffd1667 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -69,11 +69,8 @@ module ActionView # The template will be compiled if the file has not been compiled yet, or # if local_assigns has a new key, which isn't supported by the compiled code yet. def recompile?(symbol) - unless Base::CompiledTemplates.instance_methods.include?(symbol) && Base.cache_template_loading - true - else - false - end + meth = Base::CompiledTemplates.instance_method(template.method) rescue nil + !(meth && Base.cache_template_loading) end end end -- cgit v1.2.3 From 9dc258d6147c8dab772d1f041098a38389cd3e73 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 14 Jul 2008 17:40:03 -0500 Subject: Eager load Partial variable_name and counter_name. Tidy up render_partial_collection. --- actionpack/lib/action_view/renderable.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index ffcffd1667..4fda408367 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -7,16 +7,21 @@ module ActionView @@mutex = Mutex.new end - # NOTE: Exception to earlier notice. Ensure this is called before freeze def handler @handler ||= Template.handler_class_for_extension(extension) end - # NOTE: Exception to earlier notice. Ensure this is called before freeze def compiled_source @compiled_source ||= handler.new(nil).compile(self) if handler.compilable? end + def freeze + # Eager load and freeze memoized methods + handler.freeze + compiled_source.freeze + super + end + def render(view, local_assigns = {}) view._first_render ||= self view._last_render = self -- cgit v1.2.3 From dd41f66af577947ad420fbd2a44184344ad5c983 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 14 Jul 2008 19:51:43 -0500 Subject: Include Memoizable in ActionView::Template --- actionpack/lib/action_view/renderable.rb | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 4fda408367..9185045adf 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -7,20 +7,17 @@ module ActionView @@mutex = Mutex.new end + include ActiveSupport::Memoizable + def handler - @handler ||= Template.handler_class_for_extension(extension) + Template.handler_class_for_extension(extension) end + memorize :handler def compiled_source - @compiled_source ||= handler.new(nil).compile(self) if handler.compilable? - end - - def freeze - # Eager load and freeze memoized methods - handler.freeze - compiled_source.freeze - super + handler.new(nil).compile(self) if handler.compilable? end + memorize :compiled_source def render(view, local_assigns = {}) view._first_render ||= self -- cgit v1.2.3 From 001c8beb4d0999a858a8b52ad511ee1251cc3517 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 14 Jul 2008 20:02:59 -0500 Subject: memorize typo --- actionpack/lib/action_view/renderable.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack/lib/action_view/renderable.rb') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 9185045adf..f66356c939 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -12,12 +12,12 @@ module ActionView def handler Template.handler_class_for_extension(extension) end - memorize :handler + memoize :handler def compiled_source handler.new(nil).compile(self) if handler.compilable? end - memorize :compiled_source + memoize :compiled_source def render(view, local_assigns = {}) view._first_render ||= self -- cgit v1.2.3