I was wondering if there is any layout inheritance implementation in ruby. In symfony, you can do this:
layoutmain.html
Give <head> and all that here
<body>
<h3>{{title}}</h3>
{{block view}}
<div class="row">
<div class="span3">
{{content}}
</div>
</div>
{{end block}}
</body>
layout2.html
{{inherits layoutman}}
{{block view}}
<div class="container">
Structure it differently
</div>
{{end block}}
So to speak, it let's you inherit the whole template and override parts for a different layout. So the scripts etc stay as they are in the main template, but you can change the view structure. So you can reuse bits of code in the first layout
I found some liquid inheritance project on github, but it looked outdated
I use the following approach to achieve "nesting" of layouts which is the form of layout inheritance that I've found to be most useful.
In the main application helper module app/helpers/application_helper.rb
I define a helper method parent_layout
:
module ApplicationHelper
def parent_layout(layout)
@view_flow.set(:layout, self.output_buffer)
self.output_buffer = render(:file => layout)
end
end
This helper is responsible for capturing the output of the current layout and then rendering the specified parent layout with the child layout inserted when the parent yield
s.
Then in my views I can set up the layout inheritance as follows. I start with my main application layout app/views/layouts/application.html.erb
which is the child layout in this configuration:
<div class="content">
<h1><%= content_for?(:title) ? yield(:title) : 'Untitled' %></h1>
<div class="inner">
<%= yield %>
</div>
</div>
<%= parent_layout 'layouts/container' %>
The call to the helper method parent_layout
specifies that application.html.erb
is a child layout of container.html.erb
. I then define the parent layout app/views/layouts/container.html.erb
as follows:
<!DOCTYPE html>
<html>
<head>
<title>Sample</title>
</head>
<body>
<%= yield %>
</body>
</html>
The yield
in container.html.erb
yields to the "derived" (or child) layout application.html.erb
, i.e. it inserts the output of rendering application.html.erb
into the <body>
of container.html.erb
. Note that the parent_layout
call needs to come at the end of the template since it captures the output of the layout up until the point at which it is invoked.
This is based on this article but updated to work in Rails 3.2 (and, hopefully, later). I haven't tried it in Rails 4, but you'll be able to get something similar working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With