From 91a844f19cf40d44b2f30b6c7ba8d3eb98ceb00f Mon Sep 17 00:00:00 2001 From: Simon Jefford Date: Sun, 29 Jun 2008 22:39:39 +0100 Subject: [PATCH] Added a :variable_name option to render :partial.. :collection Allows you to have a local variable in a partial that has a different name than the partial file itself. --- actionpack/lib/action_controller/base.rb | 5 ++++- actionpack/lib/action_view/partial_template.rb | 19 ++++++++++--------- actionpack/lib/action_view/partials.rb | 14 +++++++------- actionpack/test/controller/new_render_test.rb | 10 ++++++++++ .../test/fixtures/test/_customer_with_var.erb | 1 + 5 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 actionpack/test/fixtures/test/_customer_with_var.erb diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 7cc6702..e5390bc 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -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, :variable_name => "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" @@ -886,7 +889,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[:variable_name]), options[:status] ) else render_for_text( diff --git a/actionpack/lib/action_view/partial_template.rb b/actionpack/lib/action_view/partial_template.rb index 0cf996c..60dc538 100644 --- a/actionpack/lib/action_view/partial_template.rb +++ b/actionpack/lib/action_view/partial_template.rb @@ -2,9 +2,9 @@ module ActionView #:nodoc: class PartialTemplate < Template #:nodoc: attr_reader :variable_name, :object - def initialize(view, partial_path, object = nil, locals = {}) + def initialize(view, partial_path, object = nil, locals = {}, variable_name = nil) @view_controller = view.controller if view.respond_to?(:controller) - set_path_and_variable_name!(partial_path) + set_path_and_variable_name!(partial_path, variable_name) super(view, @path, true, locals) add_object_to_local_assigns!(object) @@ -47,16 +47,17 @@ module ActionView #:nodoc: end || @view_controller.instance_variable_get("@#{variable_name}") end - def set_path_and_variable_name!(partial_path) + def set_path_and_variable_name!(partial_path, variable_name) if partial_path.include?('/') - @variable_name = File.basename(partial_path) - @path = "#{File.dirname(partial_path)}/_#{@variable_name}" + partial_template = File.basename(partial_path) + @variable_name = variable_name || partial_template + @path = "#{File.dirname(partial_path)}/_#{partial_template}" elsif @view_controller - @variable_name = partial_path - @path = "#{@view_controller.class.controller_path}/_#{@variable_name}" + @variable_name = variable_name || partial_path + @path = "#{@view_controller.class.controller_path}/_#{partial_path}" else - @variable_name = partial_path - @path = "_#{@variable_name}" + @variable_name = variable_name || partial_path + @path = "_#{partial_path}" end @variable_name = @variable_name.sub(/\..*$/, '').to_sym diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 6b294be..4af1cd5 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -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 = {}, variable_name = 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, variable_name) 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, variable_name) 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, variable_name) + template = ActionView::PartialTemplate.new(self, partial_path, nil, local_assigns, variable_name) 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, variable_name) 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, variable_name) template.counter = i i += 1 template.render_member(element) diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb index deda47f..eba4e5b 100644 --- a/actionpack/test/controller/new_render_test.rb +++ b/actionpack/test/controller/new_render_test.rb @@ -152,6 +152,11 @@ class NewRenderTestController < ActionController::Base render :partial => "customer", :collection => [ Customer.new("david"), Customer.new("mary") ] end + def partial_collection_with_variable_name + render :partial => "customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], + :variable_name => "customer" + end + def partial_collection_with_spacer render :partial => "customer", :spacer_template => "partial_only", :collection => [ Customer.new("david"), Customer.new("mary") ] end @@ -759,6 +764,11 @@ EOS assert_equal "Hello: davidHello: mary", @response.body end + def test_partial_collection_with_variable_name + get :partial_collection_with_variable_name + assert_equal "Hello: davidHello: mary", @response.body + end + def test_partial_collection_with_counter get :partial_collection_with_counter assert_equal "david0mary1", @response.body diff --git a/actionpack/test/fixtures/test/_customer_with_var.erb b/actionpack/test/fixtures/test/_customer_with_var.erb new file mode 100644 index 0000000..872d8c4 --- /dev/null +++ b/actionpack/test/fixtures/test/_customer_with_var.erb @@ -0,0 +1 @@ +Hello: <%= customer.name %> \ No newline at end of file -- 1.5.5.1