Skip to content

Commit

Permalink
More cleanup of ActionView and reduction in need for blocks in some c…
Browse files Browse the repository at this point in the history
…ases:

  * only one of partial_name or :as will be available as a local
  * `object` is removed
  * Simplify _layout_for in most cases.
    * Remove <% render :partial do |args| %>
    * <% render :partial do %> still works fine
  • Loading branch information
wycats committed Aug 15, 2009
1 parent 27adcd1 commit 9f5cd01
Show file tree
Hide file tree
Showing 9 changed files with 14 additions and 42 deletions.
13 changes: 5 additions & 8 deletions actionpack/lib/action_view/render/partials.rb
Expand Up @@ -223,16 +223,14 @@ def render_collection
def collection_with_template(template)
options = @options

segments, locals, as = [], @locals, options[:as] || :object
segments, locals, as = [], @locals, options[:as] || template.variable_name

variable_name = template.variable_name
counter_name = template.counter_name
locals[counter_name] = -1

collection.each do |object|
locals[counter_name] += 1
locals[variable_name] = object
locals[as] = object if as
locals[as] = object

segments << template.render(@view, locals)
end
Expand All @@ -242,14 +240,13 @@ def collection_with_template(template)
def collection_without_template
options = @options

segments, locals, as = [], @locals, options[:as] || :object
segments, locals, as = [], @locals, options[:as]
index, template = -1, nil

collection.each do |object|
template = find_template(partial_path(object))
locals[template.counter_name] = (index += 1)
locals[template.variable_name] = object
locals[as] = object if as

segments << template.render(@view, locals)
end
Expand All @@ -265,8 +262,8 @@ def render_template(template, object = @object)
@locals[:object] = @locals[template.variable_name] = object
@locals[@options[:as]] = object if @options[:as]

content = template.render(@view, @locals) do |*names|
@view._layout_for(names, &@block)
content = template.render(@view, @locals) do |*name|
@view._layout_for(*name, &@block)
end
return content if @block || !@options[:layout]
find_template(@options[:layout]).render(@view, @locals) { content }
Expand Down
22 changes: 6 additions & 16 deletions actionpack/lib/action_view/render/rendering.rb
Expand Up @@ -70,21 +70,11 @@ def render(options = {}, locals = {}, &block) #:nodoc:
# In this case, the layout would receive the block passed into <tt>render :layout</tt>,
# and the Struct specified in the layout would be passed into the block. The result
# would be <html>Hello David</html>.
def _layout_for(names, &block)
def _layout_for(name = nil)
return @_content_for[name || :layout] if !block_given? || name

with_output_buffer do
# This is due to the potentially ambiguous use of yield when
# a block is passed in to a template *and* there is a content_for()
# of the same name. Suggested solution: require explicit use of content_for
# in these ambiguous cases.
#
# We would be able to continue supporting yield in all non-ambiguous
# cases. Question: should we deprecate yield in favor of content_for
# and reserve yield for cases where there is a yield into a real block?
if @_content_for.key?(names.first) || !block_given?
return @_content_for[names.first || :layout]
else
return yield(names)
end
return yield
end
end

Expand All @@ -93,7 +83,7 @@ def _render_inline(inline, layout, options)
template = Template.new(options[:inline], "inline #{options[:inline].inspect}", handler, {})
locals = options[:locals] || {}
content = template.render(self, locals)
content = layout.render(self, locals) { content } if layout
content = layout.render(self, locals) {|*name| _layout_for(*name) } if layout
content
end

Expand Down Expand Up @@ -134,7 +124,7 @@ def _render_template(template, layout = nil, options = {}, partial = nil)
if layout
@_layout = layout.identifier
logger.info("Rendering template within #{layout.identifier}") if logger
content = layout.render(self, locals)
content = layout.render(self, locals) {|*name| _layout_for(*name) }
end
content
end
Expand Down
4 changes: 0 additions & 4 deletions actionpack/lib/action_view/template/handler.rb
Expand Up @@ -29,10 +29,6 @@ def self.call(template)
raise "Need to implement #{self.class.name}#call(template)"
end

def initialize(view = nil)
@view = view
end

def render(template, local_assigns)
raise "Need to implement #{self.class.name}#render(template, local_assigns)"
end
Expand Down
1 change: 0 additions & 1 deletion actionpack/lib/action_view/template/template.rb
Expand Up @@ -28,7 +28,6 @@ def initialize(source, identifier, handler, details)

def render(view, locals, &block)
method_name = compile(locals, view)
block ||= proc {|*names| view._layout_for(names) }
view.send(method_name, locals, &block)
rescue Exception => e
if e.is_a?(TemplateError)
Expand Down
9 changes: 0 additions & 9 deletions actionpack/test/controller/render_test.rb
Expand Up @@ -486,10 +486,6 @@ def render_using_layout_around_block
render :action => "using_layout_around_block"
end

def render_using_layout_around_block_with_args
render :action => "using_layout_around_block_with_args"
end

def render_using_layout_around_block_in_main_layout_and_within_content_for_layout
render :action => "using_layout_around_block", :layout => "layouts/block_with_layout"
end
Expand Down Expand Up @@ -1161,11 +1157,6 @@ def test_using_layout_around_block_in_main_layout_and_within_content_for_layout
assert_equal "Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n", @response.body
end

def test_using_layout_around_block_with_args
get :render_using_layout_around_block_with_args
assert_equal "Before\narg1arg2\nAfter", @response.body
end

def test_partial_only
get :partial_only
assert_equal "only partial", @response.body
Expand Down
2 changes: 1 addition & 1 deletion actionpack/test/fixtures/test/_customer_with_var.erb
@@ -1 +1 @@
<%= customer.name %> <%= customer.name %> <%= customer_with_var.name %>
<%= customer.name %> <%= customer.name %> <%= customer.name %>
2 changes: 1 addition & 1 deletion actionpack/test/fixtures/test/_hash_object.erb
@@ -1,2 +1,2 @@
<%= hash_object[:first_name] %>
<%= object[:first_name].reverse %>
<%= hash_object[:first_name].reverse %>

This file was deleted.

2 changes: 1 addition & 1 deletion actionpack/test/template/render_test.rb
Expand Up @@ -142,7 +142,7 @@ def test_render_partial_collection_as
end

def test_render_partial_collection_without_as
assert_equal "local_inspector,local_inspector_counter,object",
assert_equal "local_inspector,local_inspector_counter",
@view.render(:partial => "test/local_inspector", :collection => [ Customer.new("mary") ])
end

Expand Down

3 comments on commit 9f5cd01

@metaskills
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit broke the ability to yield(:foo) along with content_for(:foo) with regards to layouts. So normal usage like this rails cast is broken http://railscasts.com/episodes/8-layouts-and-content-for

I'll be testing some more and possibly making a recommendation, if at the least a tests that captures what should be happening. Perhaps I am missing something and content_for is not expected to talk to the layout. Right now it generates no block given errors.

@metaskills
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@masterkain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

metaskills, odd, works perfectly for me

Please sign in to comment.