aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/partials.rb
diff options
context:
space:
mode:
authorRyan Bates <ryan@railscasts.com>2008-08-21 21:02:10 -0500
committerJoshua Peek <josh@joshpeek.com>2008-08-21 21:03:33 -0500
commit1129a24caff9f1804c2bff6569c0cbd8598dfa86 (patch)
tree14a20c4c8e6e5fd05cad221de2231aefa40b849d /actionpack/lib/action_view/partials.rb
parente6a66cbd056f177f7e60341799aa95791fcfa19d (diff)
downloadrails-1129a24caff9f1804c2bff6569c0cbd8598dfa86.tar.gz
rails-1129a24caff9f1804c2bff6569c0cbd8598dfa86.tar.bz2
rails-1129a24caff9f1804c2bff6569c0cbd8598dfa86.zip
Cleanup around partial rendering
Signed-off-by: Joshua Peek <josh@joshpeek.com>
Diffstat (limited to 'actionpack/lib/action_view/partials.rb')
-rw-r--r--actionpack/lib/action_view/partials.rb83
1 files changed, 50 insertions, 33 deletions
diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb
index 074ba5a2b5..7f19532bc1 100644
--- a/actionpack/lib/action_view/partials.rb
+++ b/actionpack/lib/action_view/partials.rb
@@ -1,14 +1,15 @@
module ActionView
- # There's also a convenience method for rendering sub templates within the current controller that depends on a single object
- # (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being
- # prefixed with an underscore -- as to separate them from regular templates that could be rendered on their own.
+ # There's also a convenience method for rendering sub templates within the current controller that depends on a
+ # single object (we call this kind of sub templates for partials). It relies on the fact that partials should
+ # follow the naming convention of being prefixed with an underscore -- as to separate them from regular
+ # templates that could be rendered on their own.
#
# In a template for Advertiser#account:
#
# <%= render :partial => "account" %>
#
- # This would render "advertiser/_account.erb" and pass the instance variable @account in as a local variable +account+ to
- # the template for display.
+ # This would render "advertiser/_account.erb" and pass the instance variable @account in as a local variable
+ # +account+ to the template for display.
#
# In another template for Advertiser#buy, we could have:
#
@@ -18,24 +19,24 @@ module ActionView
# <%= render :partial => "ad", :locals => { :ad => ad } %>
# <% end %>
#
- # This would first render "advertiser/_account.erb" with @buyer passed in as the local variable +account+, then render
- # "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display.
+ # This would first render "advertiser/_account.erb" with @buyer passed in as the local variable +account+, then
+ # render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display.
#
# == Rendering a collection of partials
#
- # The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub
- # template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders
- # a partial by the same name as the elements contained within. So the three-lined example in "Using partials" can be rewritten
- # with a single line:
+ # The example of partial use describes a familiar pattern where a template needs to iterate over an array and
+ # render a sub template for each of the elements. This pattern has been implemented as a single method that
+ # accepts an array and renders a partial by the same name as the elements contained within. So the three-lined
+ # example in "Using partials" can be rewritten with a single line:
#
# <%= render :partial => "ad", :collection => @advertisements %>
#
- # This will render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. An iteration counter
- # will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
- # example above, the template would be fed +ad_counter+.
+ # This will render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. An
+ # iteration counter will automatically be made available to the template with a name of the form
+ # +partial_name_counter+. In the case of the example above, the template would be fed +ad_counter+.
#
- # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also just keep domain objects,
- # like Active Records, in there.
+ # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also
+ # just keep domain objects, like Active Records, in there.
#
# == Rendering shared partials
#
@@ -47,8 +48,9 @@ module ActionView
#
# == Rendering partials with layouts
#
- # Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally
- # for the entire action, but they work in a similar fashion. Imagine a list with two types of users:
+ # Partials can have their own layouts applied to them. These layouts are different than the ones that are
+ # specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types
+ # of users:
#
# <%# app/views/users/index.html.erb &>
# Here's the administrator:
@@ -139,36 +141,51 @@ module ActionView
extend ActiveSupport::Memoizable
private
- def render_partial(partial_path, object_assigns = nil, local_assigns = {}) #:nodoc:
- local_assigns ||= {}
+ def render_partial(options = {}) #:nodoc:
+ local_assigns = options[:locals] || {}
- case partial_path
+ case partial_path = options[:partial]
when String, Symbol, NilClass
- pick_template(find_partial_path(partial_path)).render_partial(self, object_assigns, local_assigns)
+ if options.has_key?(:collection)
+ render_partial_collection(options)
+ else
+ pick_template(find_partial_path(partial_path)).render_partial(self, options[:object], local_assigns)
+ end
when ActionView::Helpers::FormBuilder
builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '')
- render_partial(builder_partial_path, object_assigns, (local_assigns || {}).merge(builder_partial_path.to_sym => partial_path))
+ render_partial(
+ :partial => builder_partial_path,
+ :object => options[:object],
+ :locals => local_assigns.merge(builder_partial_path.to_sym => partial_path)
+ )
when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope
if partial_path.any?
- collection = partial_path
- render_partial_collection(nil, collection, nil, local_assigns)
+ render_partial(:collection => partial_path, :locals => local_assigns)
else
""
end
else
- render_partial(ActionController::RecordIdentifier.partial_path(partial_path, controller.class.controller_path), partial_path, local_assigns)
+ object = partial_path
+ render_partial(
+ :partial => ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path),
+ :object => object,
+ :locals => local_assigns
+ )
end
end
- def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc:
- return nil if collection.blank?
+ def render_partial_collection(options = {}) #:nodoc:
+ return nil if options[:collection].blank?
- local_assigns = local_assigns ? local_assigns.clone : {}
- spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : ''
+ partial = options[:partial]
+ spacer = options[:spacer_template] ? render(:partial => options[:spacer_template]) : ''
+ local_assigns = options[:locals] ? options[:locals].clone : {}
+ as = options[:as]
index = 0
- collection.map do |object|
- _partial_path ||= partial_path || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
+ options[:collection].map do |object|
+ _partial_path ||= partial ||
+ ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
path = find_partial_path(_partial_path)
template = pick_template(path)
local_assigns[template.counter_name] = index
@@ -178,7 +195,7 @@ module ActionView
end.join(spacer)
end
- def find_partial_path(partial_path)
+ def find_partial_path(partial_path) #:nodoc:
if partial_path.include?('/')
File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}")
elsif respond_to?(:controller)