Tyler
Tyler

Reputation: 11509

Render rails partial multiple times on same page

I have a partial that I'm rendering twice on the same page, but in two different locations (one is shown during standard layout, one is shown during mobile/tablet layout).

The partial is rendered exactly the same in both places, so I'd like to speed it up by storing it as a variable if possible; the partial makes an API call each time, and the 2nd call is completely unnecessary since it's a duplicate of the first API call.

Is there any way to store the HTML from the returned partial as a variable and then use that for both renders?

Edit: I'm hoping to do this without caching, as it is a very simple need and I'm looking to keep the codebase lean and readable. Is it possible to store the partial as a string variable and then reference that twice?

Upvotes: 4

Views: 4431

Answers (3)

Kyle C
Kyle C

Reputation: 4097

<% content_for :example do %>
  <%= render :your_partial %>
<%end%>

then call <%= yield :example %> or <%= content_for :example %> wherever you want your partial called.

Upvotes: 8

nruth
nruth

Reputation: 1068

I'm adding an answer to this old question because it topped Google for a search I just made.

There's another way to do this now (for quite a while), the capture helper.

<% reuse_my_partial = capture do %>
  <%= render partial: "your_partial" %>
<% end %>

<div class="visible-on-desktop"
  <%= reuse_my_partial %>
</div>

<div class="visible-on-mobile"
  <%= reuse_my_partial %>
</div>

This is simpler and slightly safer than using content_for because there is no global storage involved that something else might modify.

The rails docs linked to use instance @vars instead of local vars because they want it to be available to their layout template. That's a detail you do not need to worry about, because you're using it in the same template file.

Upvotes: 1

Thomas Fussell
Thomas Fussell

Reputation: 468

One option would be to use fragment caching. After you wrap the partial with a cache block, the second call should show the cached version of the first. For example:

<% cache do %>
  <%= render(:partial => 'my_partial') %>
<% end %>

... later in the same view ...

<% cache do %>
  <%= render(:partial => 'my_partial') %>
<% end %>

To store the result of the render to a string, you could try the render_to_string method of AbstractController. The arguments are the same as for render.

partial_string = render_to_string(:partial => 'my_partial')

Upvotes: 6

Related Questions