开发者

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?


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


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


If your /account route is bound to the account controller, you can always have a fullfeatured layout with conditional part like this

render :template => "/shared/sidebar" if controller.controller_name == "account"

(I have to admit that it does not please the eye though)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜