mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Add :as option to render a collection of partials with a custom local variable name. [#509 state:resolved] [Simon Jefford, Pratik Naik]
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
*Edge*
|
||||
|
||||
* Add :as option to render a collection of partials with a custom local variable name. #509 [Simon Jefford, Pratik Naik]
|
||||
|
||||
render :partial => 'other_people', :collection => @people, :as => :person
|
||||
|
||||
This will let you access objects of @people as 'person' local variable inside 'other_people' partial template.
|
||||
|
||||
* time_zone_select: support for regexp matching of priority zones. Resolves #195 [Ernie Miller]
|
||||
|
||||
* Made ActionView::Base#render_file private [Josh Peek]
|
||||
|
||||
@@ -702,6 +702,9 @@ module ActionController #:nodoc:
|
||||
# # builds the complete response.
|
||||
# render :partial => "person", :collection => @winners
|
||||
#
|
||||
# # Renders a collection of partials but with a custom local variable name
|
||||
# render :partial => "admin_person", :collection => @winners, :as => :person
|
||||
#
|
||||
# # Renders the same collection of partials, but also renders the
|
||||
# # person_divider partial between each person partial.
|
||||
# render :partial => "person", :collection => @winners, :spacer_template => "person_divider"
|
||||
@@ -889,7 +892,7 @@ module ActionController #:nodoc:
|
||||
if collection = options[:collection]
|
||||
render_for_text(
|
||||
@template.send!(:render_partial_collection, partial, collection,
|
||||
options[:spacer_template], options[:locals]), options[:status]
|
||||
options[:spacer_template], options[:locals], options[:as]), options[:status]
|
||||
)
|
||||
else
|
||||
render_for_text(
|
||||
|
||||
@@ -252,7 +252,7 @@ module ActionView #:nodoc:
|
||||
elsif options[:file]
|
||||
render_file(options[:file], use_full_path || false, options[:locals])
|
||||
elsif options[:partial] && options[:collection]
|
||||
render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals])
|
||||
render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals], options[:as])
|
||||
elsif options[:partial]
|
||||
render_partial(options[:partial], ActionView::Base::ObjectWrapper.new(options[:object]), options[:locals])
|
||||
elsif options[:inline]
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
module ActionView #:nodoc:
|
||||
class PartialTemplate < Template #:nodoc:
|
||||
attr_reader :variable_name, :object
|
||||
attr_reader :variable_name, :object, :as
|
||||
|
||||
def initialize(view, partial_path, object = nil, locals = {})
|
||||
def initialize(view, partial_path, object = nil, locals = {}, as = nil)
|
||||
@view_controller = view.controller if view.respond_to?(:controller)
|
||||
@as = as
|
||||
set_path_and_variable_name!(partial_path)
|
||||
super(view, @path, true, locals)
|
||||
add_object_to_local_assigns!(object)
|
||||
@@ -22,10 +23,11 @@ module ActionView #:nodoc:
|
||||
end
|
||||
|
||||
def render_member(object)
|
||||
@locals[:object] = @locals[@variable_name] = object
|
||||
@locals[:object] = @locals[@variable_name] = @locals[as] = object
|
||||
|
||||
template = render_template
|
||||
@locals[@counter_name] += 1
|
||||
@locals.delete(as)
|
||||
@locals.delete(@variable_name)
|
||||
@locals.delete(:object)
|
||||
|
||||
@@ -45,6 +47,7 @@ module ActionView #:nodoc:
|
||||
else
|
||||
object
|
||||
end || @view_controller.instance_variable_get("@#{variable_name}")
|
||||
@locals[as] ||= @locals[:object] if as
|
||||
end
|
||||
|
||||
def set_path_and_variable_name!(partial_path)
|
||||
|
||||
@@ -123,32 +123,32 @@ module ActionView
|
||||
end
|
||||
end
|
||||
|
||||
def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}) #:nodoc:
|
||||
def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc:
|
||||
return " " if collection.empty?
|
||||
|
||||
local_assigns = local_assigns ? local_assigns.clone : {}
|
||||
spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
|
||||
|
||||
if partial_path.nil?
|
||||
render_partial_collection_with_unknown_partial_path(collection, local_assigns)
|
||||
render_partial_collection_with_unknown_partial_path(collection, local_assigns, as)
|
||||
else
|
||||
render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns)
|
||||
render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, as)
|
||||
end.join(spacer)
|
||||
end
|
||||
|
||||
def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns)
|
||||
template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
|
||||
def render_partial_collection_with_known_partial_path(collection, partial_path, local_assigns, as)
|
||||
template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns, as)
|
||||
collection.map do |element|
|
||||
template.render_member(element)
|
||||
end
|
||||
end
|
||||
|
||||
def render_partial_collection_with_unknown_partial_path(collection, local_assigns)
|
||||
def render_partial_collection_with_unknown_partial_path(collection, local_assigns, as)
|
||||
templates = Hash.new
|
||||
i = 0
|
||||
collection.map do |element|
|
||||
partial_path = ActionController::RecordIdentifier.partial_path(element, controller.class.controller_path)
|
||||
template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns)
|
||||
template = templates[partial_path] ||= ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns, as)
|
||||
template.counter = i
|
||||
i += 1
|
||||
template.render_member(element)
|
||||
|
||||
@@ -152,6 +152,10 @@ class NewRenderTestController < ActionController::Base
|
||||
render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ]
|
||||
end
|
||||
|
||||
def partial_collection_with_as
|
||||
render :partial => "customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer
|
||||
end
|
||||
|
||||
def partial_collection_with_spacer
|
||||
render :partial => "customer", :spacer_template => "partial_only", :collection => [ Customer.new("david"), Customer.new("mary") ]
|
||||
end
|
||||
@@ -763,6 +767,11 @@ EOS
|
||||
assert_equal "Hello: davidHello: mary", @response.body
|
||||
end
|
||||
|
||||
def test_partial_collection_with_as
|
||||
get :partial_collection_with_as
|
||||
assert_equal "david david davidmary mary mary", @response.body
|
||||
end
|
||||
|
||||
def test_partial_collection_with_counter
|
||||
get :partial_collection_with_counter
|
||||
assert_equal "david0mary1", @response.body
|
||||
|
||||
1
actionpack/test/fixtures/test/_customer_with_var.erb
vendored
Normal file
1
actionpack/test/fixtures/test/_customer_with_var.erb
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<%= customer.name %> <%= object.name %> <%= customer_with_var.name %>
|
||||
@@ -54,6 +54,11 @@ class ViewRenderTest < Test::Unit::TestCase
|
||||
def test_render_partial_collection
|
||||
assert_equal "Hello: davidHello: mary", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ])
|
||||
end
|
||||
|
||||
def test_render_partial_collection_as
|
||||
assert_equal "david david davidmary mary mary",
|
||||
@view.render(:partial => "test/customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer)
|
||||
end
|
||||
|
||||
# TODO: The reason for this test is unclear, improve documentation
|
||||
def test_render_partial_and_fallback_to_layout
|
||||
|
||||
Reference in New Issue
Block a user