# Nesting layouts

**URL:** <https://discuss.rubyonrails.org/t/nesting-layouts/75756>\
**Category:** A May Of WTFs\
**Created:** [June 23, 2020, 8:37pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756 "2020-06-23T20:37:49Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Maxime\_Handfield\_Lap](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/maxime_handfield_lap/32/1232_2.png) [@Maxime\_Handfield\_Lap](https://discuss.rubyonrails.org/u/Maxime_Handfield_Lap)\
**Post date:** [June 23, 2020, 8:37pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/1 "2020-06-23T20:37:49Z")

</div>

I feel the view system is lacking simple a system to just create a “sub layout”. Intuitively its pretty simple, but the guide for it is a bit rough i find: [Layouts and Rendering in Rails — Ruby on Rails Guides](https://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts)

I mean, lets say i want an “administration” layout. It would be like application, but have an extra menu within the yield of the “application” layout.

In my mind, this is what I would want to do:

```ruby
<%= extends :application do %>
  # Put my menu here
  = yield
<% end %>

```

The guide currently suggests using `content_for?(:content) ? yield(:content) : yield` in the application layout, and then using content\_for and `<%= render template: "layouts/application" %>` in the sub layout. But the `extends` approach seems much more intuitive to me.

The big advantage of `extends` above is that parent layout wouldn’t have to care / be modified.

A gem exists which does this. It seems to still work in Rails 6, but it hasn’t been changed since 2016. The code for the feature is 7 lines: [nestive/layout\_helper.rb at master · rwz/nestive · GitHub](https://github.com/rwz/nestive/blob/master/lib/nestive/layout_helper.rb#L84)

With this feature, think of how simple the guide for nested layouts would be. [Layouts and Rendering in Rails — Ruby on Rails Guides](https://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts) It would should an example of `extend` and then mention that if modifications to the content of the application layout are needed, they should look at the `content_for` method.

Any thoughts? I’d be happy to look into making a PR if feedback is positive

---

<div class="post-metadata">

**Author:** ![e\_a](https://avatars.discourse-cdn.com/v4/letter/e/9fc348/32.png) [@e\_a](https://discuss.rubyonrails.org/u/e_a)\
**Post date:** [June 24, 2020, 2:12pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/2 "2020-06-24T14:12:31Z")

</div>

What about using the block form of `render` with the `layout` option. So:

```ruby
<%= render layout: 'administration' do %>
  My admin content
<% end %>

```

Then in `administration.html.erb`:

```nohighlight
# Put my menu here
yield

```

This is documented on the [render helper](https://api.rubyonrails.org/classes/ActionView/Helpers/RenderingHelper.html). This seems to be existing functionality that accomplishes what you want.

I wonder if the Guides should be updated to suggest this approach rather than the `content_for` approach?

---

<div class="post-metadata">

**Author:** ![Maxime\_Handfield\_Lap](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/maxime_handfield_lap/32/1232_2.png) [@Maxime\_Handfield\_Lap](https://discuss.rubyonrails.org/u/Maxime_Handfield_Lap)\
**Post date:** [June 24, 2020, 2:51pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/3 "2020-06-24T14:51:41Z")

</div>

Interesting, I was not aware of that feature.

I will need to try to it be sure, but my initial understanding of the doc (which oddly is not on render, but on \_layout\_for ) is that using this approach would break the interaction of yield / content\_for. So if the “application” layout does `yield :side_bar`, that would just call the block passed by the “administration” with the argument :side\_bar, which without specific handling in that block, would just print “My admin content” again…

I will try it out tomorrow when I’m at work.

---

<div class="post-metadata">

**Author:** ![joallard](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/joallard/32/990_2.png) [@joallard](https://discuss.rubyonrails.org/u/joallard)\
**Post date:** [June 24, 2020, 5:40pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/4 "2020-06-24T17:40:45Z")

</div>

Actually, thats the one thing I’ve always thought Middleman got better than Rails: instead of eg, calling ‘render :admin’ in the general layout, you would ‘wrap\_layout :application’ inside the specific (admin) one. It’s much more ergonomic this way.

---

<div class="post-metadata">

**Author:** ![akaspick](https://avatars.discourse-cdn.com/v4/letter/a/5daacb/32.png) [@akaspick](https://discuss.rubyonrails.org/u/akaspick)\
**Post date:** [June 25, 2020, 5:13pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/5 "2020-06-25T17:13:26Z")

</div>

I just use the partial and layout options together…

```ruby
render partial: 'list', layout: 'list_layout'

```

---

<div class="post-metadata">

**Author:** ![pinzonjulian](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/pinzonjulian/32/10485_2.png) [@pinzonjulian](https://discuss.rubyonrails.org/u/pinzonjulian)\
**Post date:** [June 28, 2020, 10:42pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/6 "2020-06-28T22:42:19Z")

</div>

I’ve needed this for so long!

---

<div class="post-metadata">

**Author:** ![jasl](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/jasl/32/653_2.png) [@jasl](https://discuss.rubyonrails.org/u/jasl)\
**Post date:** [July 4, 2020, 8:15pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/7 "2020-07-04T20:15:36Z")

</div>

Rails actually support nesting layout, but seems no doc point this out.

You can see how I do this: [https://github.com/jasl/cybros\_core/blob/master/app/views/layouts/application.html.erb#L24](https://github.com/jasl/cybros_core/blob/master/app/views/layouts/application.html.erb#L24)

---

<div class="post-metadata">

**Author:** ![Trycia](https://avatars.discourse-cdn.com/v4/letter/t/49beb7/32.png) [@Trycia](https://discuss.rubyonrails.org/u/Trycia)\
**Post date:** [December 14, 2020, 7:51pm UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/8 "2020-12-14T19:51:31Z")

</div>

It’s like HTML pages that use crazy nested tables. It is slower and more resource intensive (use DDMS to analyze it), and much more complicated than a RelativeLayout.

Once you learn to use RelativeLayout, you’ll actually prefer to avoid LinearLayout. Everything’s so much easier with it.

---

<div class="post-metadata">

**Author:** ![rewritten](https://sea2.discourse-cdn.com/rubyonrails/user_avatar/discuss.rubyonrails.org/rewritten/32/2686_2.png) [@rewritten](https://discuss.rubyonrails.org/u/rewritten)\
**Post date:** [December 16, 2020, 11:08am UTC](https://discuss.rubyonrails.org/t/nesting-layouts/75756/9 "2020-12-16T11:08:33Z")

</div>

With support for `render object_that_responds_to_render_in`, I think this issue (and the whole layout thing) will go away sooner than later. In the end a layout can just be a renderable object that has your controller’s view in a block, so there is no limit on nesting.

```nohighlight
<!-- some_layout.html.erb -->
<%= render MyLayout.new(...) do %>
  <%= render SomeSublayout.new(...) do %>
    <%= yield %>
  <% end %>
<% end %>

```
