Rails Multipart Layouts and Yielding Sections

app/views/layouts/application.html.erb.
<!DOCTYPE html> <html> <head> <title>Myapp</title> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> </head> <body> <%= yield %> </body> </html>The highlighted line is the important one. That <%= yield %> tells Ruby on Rails that whatever view you load just drop it right there. That's great! Now we have a simple base layout that houses our imports and basic structure and CSS and we simply drop in our own content inside of this. Let's say we want to take it a step further. What if we want a left and a right side bar which is unique to each of our views? We just need to change our basic layout a little bit to add those columns and then update our view template code to take advantage of our new structure.
Yield Sections
app/views/layouts/application.html.erb
<!DOCTYPE html> <html> <head> <title>Myapp</title> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> </head> <body> <div id="left" class="sidebar"> <%= yield :left %> </div> <div id="content"> <%= yield %> </div> <div id="right" class="sidebar"> <%= yield :right %> </div> </body> </html>
app/views/MODEL/new.html.erb
<% content_for :left do %>
<h2>Left Side</h2>
<ul>
<li>...</li>
</ul>
<% end %>
<% content_for :right do %>
<h2>Right Side</h2>
<ul>
<li>...</li>
</ul>
<% end %>
<h1>Content Heading></h1>
Following the suggestion of Obie Fernandez and Kevin Faustino in their book The Rails 4 Waycontent_for will be dropped in that unnamed yield in the layout.
Render Partials
That's all well and good but what if you don't want a specific set of sidebar content for every single view. Maybe a shared partial for the right bar will work great. In that case you'll need to use the render method in your template to generate the template for you. Here is the example from above but using a shared right side bar template.app/views/layouts/application.html.erb
<!DOCTYPE html> <html> <head> <title>Myapp</title> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> </head> <body> <div id="left" class="sidebar"> <%= yield :left %> </div> <div id="content"> <%= yield %> </div> <div id="right" class="sidebar"> <%= render 'shared/right' %> </div> </body> </html>
app/views/shared/_right.html.erb
<h2>Right Side</h2> <ul> <li>...</li> </ul>
Render Partials with Variables
You can even pass in variables to your partials. Let's say our right side bar takes advantage of some user data. We just pass the user variable to the render with a comma and a hash type variable being passed.app/views/layouts/application.html.erb
<!DOCTYPE html> <html> <head> <title>Myapp</title> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> </head> <body> <div id="left" class="sidebar"> <%= yield :left %> </div> <div id="content"> <%= yield %> </div> <div id="right" class="sidebar"> <%= render 'shared/right', user: user %> </div> </body> </html>
app/views/shared/_right.html.erb
<h2>Right Side</h2> <h3><%= user.name %></h3> <ul> <li>...</li> </ul>Pretty cool, right? I hope this introduction to layouts and partials was helpful. If there are any problems with my examples or if you have any questions please feel free to leave a comment below.
Comments
Join the discussionNo comments yet. Be the first to comment.




