diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 869d4704dd3b7..78ac05389ccdc 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,5 +1,7 @@ ## Rails 4.0.0 (unreleased) ## +* Adds support for layouts when rendering a partial with a given collection. *serabe* + * Allows the route helper `root` to take a string argument. For example, `root 'pages#main'`. *bcardarella* * Forms of persisted records use always PATCH (via the `_method` hack). *fxn* diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index 3628b935b7d6b..245a19deecb28 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -158,6 +158,43 @@ module ActionView # Name: <%= user.name %> # # + # If a collection is given, the layout will be rendered once for each item in the collection. Just think + # these two snippets have the same output: + # + # <%# app/views/users/_user.html.erb %> + # Name: <%= user.name %> + # + # <%# app/views/users/index.html.erb %> + # <%# This does not use layouts %> + # + # + # <%# app/views/users/_li_layout.html.erb %> + #
  • + # <%= yield %> + #
  • + # + # <%# app/views/users/index.html.erb %> + # + # + # Given two users whose names are Alice and Bob, these snippets return: + # + # + # # You can also apply a layout to a block within any template: # # <%# app/views/users/_chief.html.erb &> @@ -238,7 +275,14 @@ def render_collection spacer = find_template(@options[:spacer_template]).render(@view, @locals) end + if layout = @options[:layout] + layout = find_template(layout) + end + result = @template ? collection_with_template : collection_without_template + + result.map!{|content| layout.render(@view, @locals) { content } } if layout + result.join(spacer).html_safe end @@ -342,9 +386,10 @@ def collection_with_template locals[as] = object segments << template.render(@view, locals) end - + segments end + def collection_without_template segments, locals, collection_data = [], @locals, @collection_data diff --git a/actionpack/test/fixtures/test/_b_layout_for_partial.html.erb b/actionpack/test/fixtures/test/_b_layout_for_partial.html.erb new file mode 100644 index 0000000000000..e918ba8f8303b --- /dev/null +++ b/actionpack/test/fixtures/test/_b_layout_for_partial.html.erb @@ -0,0 +1 @@ +<%= yield %> \ No newline at end of file diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 7347e15373397..122b07d348734 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -238,6 +238,10 @@ def test_render_partial_with_nil_collection_should_return_nil def test_render_partial_with_nil_values_in_collection assert_equal "Hello: davidHello: Anonymous", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), nil ]) end + + def test_render_partial_with_layout_using_collection_and_template + assert_equal "Hello: AmazonHello: Yahoo", @view.render(:partial => "test/customer", :layout => 'test/b_layout_for_partial', :collection => [ Customer.new("Amazon"), Customer.new("Yahoo") ]) + end def test_render_partial_with_empty_array_should_return_nil assert_nil @view.render(:partial => [])