Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending an existing layout in Rails

I have my main application layout, but then I have an /account section of my site which has exactly the same layout as the application layout markupwise, except the /account pages have an added sidebar in the content area of the layout.

Rather than blatantly copy the application layout and create a nearly redundant "account" layout, I'd like to extend the application layout, adding the sidebar in the content area.

So I have something like this in my application layout:

<html>
<body>

<div id="content">

<%= yield %>

</div>

</body>
</html>

and I want

<html>
<body>

<div id="content">

  <div id="sidebar"></div>

  <%= yield %>

</div>

</body>
</html>

Is there a way to accomplish this without copying code?

like image 785
Chad Johnson Avatar asked Oct 06 '10 17:10

Chad Johnson


2 Answers

You can have more than one yield in a layout, simply give the additional ones a name:

<html>
<body>
  <div id="content">
    <%= yield :sidebar %>
    <%= yield %>
  </div>
</body>
</html>

You can add HTML for that yield by using the content_for method

<% content_for :sidebar do -%>
  <div id="sidebar"></div>
<% end -%>

But you'll have to add that to every view you want to have a sidebar. Instead, create views/layouts/application_with_sidebar.html.erb

<% content_for :sidebar do -%>
  <div id="sidebar"></div>
<% end -%>

<%= render :file => 'layouts/application' %>

Further reading

If you'd prefer to keep the number of yields to a minimum, you can nest your layouts instead.

views/layouts/application.html.erb

<html>
<body>
  <div id="content">
    <%= yield(:with_sidebar) or yield %>
  </div>
</body>
</html>

views/layouts/application_with_sidebar.html.erb

<% content_for :with_sidebar do -%>
  <div id="sidebar"></div>
<% end -%>

<%= render :file => 'layouts/application' %>

controllers/accounts_controller.rb

class AccountsController < ApplicationController
  layout 'application_with_sidebar'
  ...
end
like image 54
Adam Lassek Avatar answered Sep 19 '22 06:09

Adam Lassek


Often you'll have the same situation for other parts of the site in which case it may make sense to use nested layouts.

http://guides.rubyonrails.org/v2.3.8/layouts_and_rendering.html#using-nested-layouts

like image 35
mark Avatar answered Sep 22 '22 06:09

mark