views:

25

answers:

2

In one of my views I apply a layout to a block of code:

# In app/views/sessions/new.html.erb
<% render :layout => 'home/shadow_box' do %>
  #... code for sign in form here
<% end %>

The layout is a div that has png shadows on all four sides.

Since I use this layout all over my site, I want to pass a variable to the layout that specifies the width of the shadowed div. I tried using content for in the code block:

# In app/views/sessions/new.html.erb
<% render :layout => 'home/shadow_box' do %>
  <% content_for :box_width %>640<% end %>
  #... code for sign in form here
<% end %>

# In app/views/home/_shadow_box.html.erb
<div class="shadow-one" style="width:<%= yield :box_width %>;">
  <div class="corner-a"></div>
  <div class="corner-b"></div>
  <div class="shadow-two">
    <div class="shadow-three">
      <div class="shadow-four">
        <%= yield %>
      </div>
    </div>
  </div>
</div>

This didn't work and instead resulted in a double render of the entire code block.

What's the best way to tackle this problem?

A: 

First you need to know the difference between layouts and partials. Partials are generally from the view but can also be used from the controller if you are using ajax. Layouts are almost always used in the controller.

First create a file in a shared folder such as application/ and in this folder put a file call it whatever you want but it will contain the material that you want to include all over your site. Then when you pass a variable to a partial it's called in the partial as a local variable. Also with partials you don't need to say render :partial => you just put render 'application/some_file'

So from the view you want this:

<%= render 'application/your_file', :div_size => '600' %>

And then from the partial in the folder such as application/your_file.html.erb do this:

<div style="width:<%= div_width %>px;">
   content
</div>
Sam
I understand the difference btwn layouts and partials... I'm not talking about the kind of layouts specified globally for the entire action. A partial doesn't suite my needs here because what I have is a container (several divs to make a shadowed container) that I want to throw whatever into, be it a code block or even a partial (i.e. render 'inventories/show', :layout => 'shadow_box').
telecasterrok
A: 

Figured it out.

From the API: "You can also yield multiple times in one layout and use block arguments to differentiate the sections."

Solution:

# In app/views/sessions/new.html.erb
<% render :layout => 'home/shadow_box' do | section | %>
  <%- case section when :box_width -%>
    #width goes here. I.e., 640px
  <%- when :content -%>
    #code block goes here
  <% end -%>
<% end %>

#In app/views/home/_shadow_box.html.erb
<div class="shadow-one" style="width:<%= yield :box_width %>;">
  <div class="corner-a"></div>
  <div class="corner-b"></div>
  <div class="shadow-two">
    <div class="shadow-three">
      <div class="shadow-four">
        <%= yield :content %>
      </div>
    </div>
  </div>
</div>
telecasterrok