Sub-layouts

I have a nice layout for my app, but for some actions I want to use a
shared sub layout. Anyone have ideas what the best practice would
be? I have a method that works, but I am not sure if it is the ‘rails
way’ of doing things, anyone care to critique it? I have tried the
following…

  1. making my action template call
    render :partial, :collection, :layout. The good new here is that it
    wraps the layout around the whole collection (not around each item in
    the collection) and doesn’t blow away my main layout. The bad news is
    the sub-layout and collection are repeated as many times as there are
    items in the collection. This seems like a rails bug. The layout
    should be applied once around the whole collection, or once for each
    item in the collection, not both.

  2. applying a layout to the render :action in the controller. This
    blows away my main layout. This is because i am rendering a template,
    not a partial, right?

  3. using content_for to define a sub-layout. this works, but I feel
    like there should be an easier way. i am also not sure yet what would
    happen when i don’t want a sub-layout. I guess I could make a
    _no_sub_layout.html.erb that just yields, or put the content all
    inside of the content_for block…I have a few other ideas too. One
    possible benefit is that I think you could keep nesting sub-layouts
    pretty easily if you wanted. Here is a simplified version of this
    solution.

layout.html.erb

head stuff some stuff <%= yield :sublayout %> some stuff

index.html.erb
<% content_for :sublayout do -%>
<%= render :partial =>“sublayout” %>
<% end -%>

<% for item in @collection do -%>
<%= render :partial => “item” -%>
<% end -%>

_sublayout.html.erb
some stuff
<%= yield %>
some stuff

_item.html.erb
<%= h item.name %>

I don’t know why I though the third method worked…anyway, a little
tweaking gives me this, which does work. Instead of the content_for I
pass a rendered collection into _sublayout as a local variable named
content.

layout.html.erb

head stuff some stuff <%= yield %> some stuff

index.html.erb
<%= render :partial =>“sublayout”, :locals => { :content =>
(render :partial => “item”, :collection => @items) } -%>

_sublayout.html.erb
some stuff
<%= content %>
some stuff

_item.html.erb
<%= h item.name %>

On Oct 1, 1:04 pm, Garrett B. [email protected]

Have you checked out Ryan B. railscasts - you might try

He also has some other ones on layouts. His railscasts are great
Owen

On Oct 1, 10:32 am, Garrett B. [email protected]

I have seen his website before, but the videos don’t play on my
computer. Recently my computer just started having some problems with
video files and I haven’t taken the time to figure out the problem.
Regardless I think I have pieced together something decent, kind of a
cross between methods 3 and 4. The only thing that kinda still bugs
me is needing a no_sublayout.html.erb. I have been trying in vain to
find a why to get the the main_layout to choose between
yield :sublayout or yield :layout. It looks like this…

views/layouts/main_layout.html.erb
some html
<%= yield :sublayout %>
some html

views/items/index.html.erb
render :partial => “item”, :collection => @items

views/items/_item.html.erb
<%= h item.name $>

views/layouts/sublayout.html.erb
<% content_for sublayout do -%>
some html
<%= yield %>
some html
<% end -%>
render :file=>“layouts/main_layout.html.erb”

views/layouts/no_sublayout.html.erb
<% content_for sublayout do -%>
<%= yield %>
<% end -%>
render :file=>“layouts/main_layout.html.erb”

controllers/items_controller.rb
layout :choose_layout
normal controller stuff
private
def choose_layout
if action_name == “index” “sublayout”
else “no_sublayout”
end
end

now on to the next iteration…i am using this with nested resources
and would like to keep nesting more sublayouts, hahaha.
G