Module: ActionView::Partials

Defined in:
lib/action_view/partials.rb

Overview

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.rhtml” 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:

<%= render :partial => "account", :locals => { :account => @buyer } %>

<% for ad in @advertisements %>
  <%= render :partial => "ad", :locals => { :ad => ad } %>
<% end %>

This would first render “advertiser/_account.rhtml” with @buyer passed in as the local variable account, then render “advertiser/_ad.rhtml” 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:

<%= render :partial => "ad", :collection => @advertisements %>

This will render “advertiser/_ad.rhtml” 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.

Rendering shared partials

Two controllers can share a set of partials and render them like this:

<%= render :partial => "advertisement/ad", :locals => { :ad => @advertisement } %>

This will render the partial “advertisement/_ad.rhtml” regardless of which controller this is being called from.

Instance Method Summary collapse

Instance Method Details

#render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) ⇒ Object

Deprecated, use render :partial


49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/action_view/partials.rb', line 49

def render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc:
  path, partial_name = partial_pieces(partial_path)
  object = extracting_object(partial_name, local_assigns, deprecated_local_assigns)
  local_assigns = extract_local_assigns(local_assigns, deprecated_local_assigns)
  local_assigns = local_assigns ? local_assigns.clone : {}
  add_counter_to_local_assigns!(partial_name, local_assigns)
  add_object_to_local_assigns!(partial_name, local_assigns, object)

  ActionController::Base.benchmark("Rendered #{path}/_#{partial_name}", Logger::DEBUG, false) do
    render("#{path}/_#{partial_name}", local_assigns)
  end
end

#render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil) ⇒ Object Also known as: render_collection_of_partials

Deprecated, use render :partial, :collection


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/action_view/partials.rb', line 63

def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil) #:nodoc:
  collection_of_partials = Array.new
  counter_name = partial_counter_name(partial_name)
  local_assigns = local_assigns ? local_assigns.clone : {}
  collection.each_with_index do |element, counter|
    local_assigns[counter_name] = counter
    collection_of_partials.push(render_partial(partial_name, element, local_assigns))
  end

  return " " if collection_of_partials.empty?

  if partial_spacer_template
    spacer_path, spacer_name = partial_pieces(partial_spacer_template)
    collection_of_partials.join(render("#{spacer_path}/_#{spacer_name}"))
  else
    collection_of_partials.join
  end
end