Skip to content
Browse files

Eliminate internal render stack since we only need its head and tail

  • Loading branch information...
1 parent 9230678 commit 82c6597dc244715c40151c7eb10f2016ed5ebb47 @jeremy jeremy committed Mar 12, 2009
Showing with 27 additions and 17 deletions.
  1. +16 −2 actionpack/lib/action_view/base.rb
  2. +11 −15 actionpack/lib/action_view/renderable.rb
View
18 actionpack/lib/action_view/base.rb
@@ -221,10 +221,12 @@ def include(*args)
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
@assigns = assigns_for_first_render
@assigns_added = nil
- @_render_stack = []
@controller = controller
@helpers = ProxyModule.new(self)
self.view_paths = view_paths
+
+ @_first_template = nil
+ @_current_template = nil
end
attr_reader :view_paths
@@ -286,7 +288,19 @@ def template_format
# Access the current template being rendered.
# Returns a ActionView::Template object.
def template
- @_render_stack.last
+ @_current_template
+ end
+
+ def template=(template) #:nodoc:
+ @_first_template ||= template
+ @_current_template = template
+ end
+
+ def with_template(current_template)
+ last_template, self.template = template, current_template
+ yield
+ ensure
+ self.template = last_template
end
private
View
26 actionpack/lib/action_view/renderable.rb
@@ -27,23 +27,19 @@ def method_name_without_locals
def render(view, local_assigns = {})
compile(local_assigns)
- stack = view.instance_variable_get(:@_render_stack)
- stack.push(self)
-
- view.send(:_evaluate_assigns_and_ivars)
- view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
-
- result = view.send(method_name(local_assigns), local_assigns) do |*names|
- ivar = :@_proc_for_layout
- if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar))
- view.capture(*names, &proc)
- elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
- view.instance_variable_get(ivar)
+ view.with_template self do
+ view.send(:_evaluate_assigns_and_ivars)
+ view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
+
+ view.send(method_name(local_assigns), local_assigns) do |*names|
+ ivar = :@_proc_for_layout
+ if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar))
+ view.capture(*names, &proc)
+ elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
+ view.instance_variable_get(ivar)
+ end
end
end
-
- stack.pop
- result
end
def method_name(local_assigns)

3 comments on commit 82c6597

@josevalim
Ruby on Rails member

Jeremy, mostly for backwards compatibility, can’t @_first_template be called @_first_render?

Plugin developers (like me :P) will be grateful!
Thanks!

@iain
iain commented on 82c6597 Mar 12, 2009

or…. you’re hacking in too deep, depending on the name of instance vars that are prepended with an underscore (very private instance vars?)… ;)

@josevalim
Ruby on Rails member

No that deep. :)

I just need to know the first template rendered to append a link for it in your views, so I’m actually just doing a instance_variable_get. :P

See my rails-footnotes project. :)

Please sign in to comment.
Something went wrong with that request. Please try again.