Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two-part Rails layouts

My web pages consist of two parts, let's say top and bottom (except header and footer -- those are consistent across pages). What is the best practice to dynamically generate those parts depending on the action?

One approach I have come up with is to have view for the top and partial for the bottom; in the layout call yield for the top and render partial for the bottom. The name of the partial is dynamically substituted depending on the action.

Not sure it is the best way to do it.

like image 689
Pavel Bastov Avatar asked Jan 25 '10 12:01

Pavel Bastov


2 Answers

I think your idea is fine. In your views you could do:

<%- content_for :top do -%>
  […]
<%- end -%>

<%- content_for :bottom do -%>
  <%= render @partial_name %>
<%- end -%>

Of course you should check whether the partial exist and provide some default behavior. But I think you're aware of that anyway.

And then in your layout:

<div id="top">
  <%= yield :top %>
</div>

<div id="bottom">
  <%= yield :bottom %>
</div>
like image 79
nocksock Avatar answered Oct 12 '22 05:10

nocksock


Here is a very simplified version of a view DSL I've used in the past. Worked well for us. In reality we parameterized the the helper methods so we could choose from many layout partials on the fly (to have pages with sidebars, multiple columns, etc).

# app/views/shared/_screen.erb
<div id="screen">
  <div class="screen_header">
 <%= yield :screen_header %>
  </div>
  <div class="screen_body">
 <%= yield :screen_body
  </div>
  <div class="bottom">
    <%= yield :footer %>
  </div>
</div>

# app/helpers/screen_helper.rb
module ScreenHelper

 def screen(&block)
  yield block
  concat(render :partial => 'shared/screen')
 end

 def screen_header
   content_for :screen_header do
   yield
  end
 end

 def screen_body
  content_for :screen_body do
   yield
  end
 end

 def footer
  content_for :footer do
   yield
  end
 end
end

# app/views/layouts/application.erb
# only showing the body tag
<body>
  <%= yield :layout
<body>

# Example of a page
# any of the sections below (except screen) may be used or omitted as needed.
# app/views/users/index.html.erb
<% screen do %>
  <% screen_header do %>
  Add all html and/or partial renders for the header here.
  <%end%>
  <% screen_body do %>
    Add all html and/or partial renders for the main content here.
  <% end %>
  <% footer do %>
 Add all the html and/or partial renders for the footer content here.
  <% end %>
<% end %>
like image 23
ffoeg Avatar answered Oct 12 '22 07:10

ffoeg