Assign a rendered partial to an instance variable
Asked Answered
T

2

7

In rails 4, I want to render a partial (say the footer) on anywhere of a page.

In home_controller.rb, I have this within a class:

def spree_application
 @test = render :partial => 'spree/shared/footer'
end

When I go to the index page and added:

<%= @test %>

Nothing happens. I know I can render within the index page but Im asking if there is a way to assign the rendered link to a variable.

Thanks!

Edit: I have made a mistake with this question. I have defined: spree_application

Table answered 13/5, 2014 at 8:42 Comment(7)
According to the link, your template file should have underscore in it like _footer.html.erb, see api.rubyonrails.org/classes/ActionView/PartialRenderer.htmlDioptase
@SajanChandran - render adds it automaticaly if key :partial is specified.Moraine
Could you tell what exactly you're trying to achieve here? I don;t think this is the best practice to store partial results into instance variables in the controller, this is definitively concern of the view.Moraine
The main reason is, if I add an image link in the application.html.erb, it shows up on all page and I do not want that. I only need it to show on the index page but without adding and code in the index.html.erb file.Table
Why without adding code to index view? I'm asking because there might be cleaner way of doing thisMoraine
I need full width and <%= yeild %> is wrapped in a container. I want <%= @test %> outside of the container.Table
"instance" variable, not "instant" variableMayfield
M
9

Controller's render method is different than view's one. You want to execute it in a view context:

 @test = view_context.render 'spree/shared/footer'

The main difference between this method and render_to_string is that this returns html_safe string, so html tags within your <%= @test %> won't be escaped.

UPDATE:

However this is not the proper way of dealing with your problem. You are looking for 'content_for'. This method allows you to build part of the view, which can be used within the layout. All you need to do is to modify your layout:

# Your application layout
<html>
  <head>
  ...
  </head>
  <body>
    yield :image
    <div id="wrapper">
      yield
    </div>
  </body>
</html>

Then within your view, you can specify what is to be displayed as yield :image with

<% content_for :image do %>
  <%# Everything here will be displayed outside of the wraper %>
<% end %> 
Moraine answered 13/5, 2014 at 8:56 Comment(4)
This does not work when I added <%= @test %>. What am I doing wrong?Table
@user3581788 - Are you calling it in spree_application.html.erb or in the layout? It won't work in the layout.Moraine
Yes I am calling it in the spree_application.html.erb. I will try what you said and report back. Thanks!Table
+1. The first part of this answer (which directly answer's the OP's question) is very useful in the case where you have some content that is expensive to compute but needs to be rendered mutliple times on the same page. You can render it once to an HTML string and then output the string at each location where it is required on the page.Burks
E
11

you are looking for render_to_string

Enos answered 13/5, 2014 at 8:55 Comment(0)
M
9

Controller's render method is different than view's one. You want to execute it in a view context:

 @test = view_context.render 'spree/shared/footer'

The main difference between this method and render_to_string is that this returns html_safe string, so html tags within your <%= @test %> won't be escaped.

UPDATE:

However this is not the proper way of dealing with your problem. You are looking for 'content_for'. This method allows you to build part of the view, which can be used within the layout. All you need to do is to modify your layout:

# Your application layout
<html>
  <head>
  ...
  </head>
  <body>
    yield :image
    <div id="wrapper">
      yield
    </div>
  </body>
</html>

Then within your view, you can specify what is to be displayed as yield :image with

<% content_for :image do %>
  <%# Everything here will be displayed outside of the wraper %>
<% end %> 
Moraine answered 13/5, 2014 at 8:56 Comment(4)
This does not work when I added <%= @test %>. What am I doing wrong?Table
@user3581788 - Are you calling it in spree_application.html.erb or in the layout? It won't work in the layout.Moraine
Yes I am calling it in the spree_application.html.erb. I will try what you said and report back. Thanks!Table
+1. The first part of this answer (which directly answer's the OP's question) is very useful in the case where you have some content that is expensive to compute but needs to be rendered mutliple times on the same page. You can render it once to an HTML string and then output the string at each location where it is required on the page.Burks

© 2022 - 2024 — McMap. All rights reserved.