layout
layout(template_name, conditions = {})If a layout is specified, all actions rendered through render and render_action will have their result assigned to @content_for_layout, which can then be used by the layout to insert their contents with <%= @content_for_layout %>. This layout can itself depend on instance variables assigned during action performance and have access to them as any normal template would.
8Notes
Turn layout off
If you don't want a layout rendered, just put:
layout nil
in your controller.
Function to Determine Layout
Sometimes its nice to have different layouts choosen automagicly:
class ApplicationController < ActionController::Base layout :determine_layout def determine_layout if is_admin? "admin" else "application" end ... end
Required Reading
The details for using layout (such as possible values for the conditions hash) can be found in ActionController::Layout::ClassMethods.
Turn layout off with render
Thats awkward, but the code below does not turn layout off:
render :action => "short_goal", :layout => nil
you must use false
render :action => "short_goal", :layout => false
Caveat when using dynamic layouts
Worth noting that if you have a controller which inherits from another controller which has a layout, and in this child controller you're determining the layout at runtime using a method for specific actions, the other actions you are excluding will not inherit the layout from the parent controller.
For example, if you've got this
class BaseController < ApplicationController
layout "public"
end
class OrdersController < BaseController
layout :determine_layout, :only => :new
# index, show, new, create, edit, update, destroy ...
end
then OrdersController#index, #show, and #edit won't get the "public" layout -- in fact they won't get a layout at all. So you'll need to do this instead:
class OrdersController < BaseController
layout :determine_layout, :only => :new
layout "public", :except => :new
# ...
end
Using a specific layout
To choose the layout (or no layout) for a method call the render method with a :layout option.
Re: Caveat when using dynamic layouts
Since there's no way to edit posts on here, I need to correct myself and say that what I posted before doesn't work, since you can't specify layout multiple times:
class OrdersController < BaseController layout :determine_layout, :only => :new layout "public", :except => :new
...
end
So don't do that. The only way to ensure that the other actions get the default theme is to drop :only/:except and do the conditions yourself:
class OrdersController < BaseController layout :determine_layout
private def determine_layout %w(new).include?(action_name) ? "some_layout" : "public" end end
All this to say, beware of :only/:except -- they aren't as useful as you think they are.
Disable layout on ajax
In actions that may or may not be loaded via ajax I use: render :layout => !request.xhr? For an entire controller I might use something like: layout :has_layout?
private
def has_layout?
request.xhr? ? false : controller_name
end
What seems unusual is that layout true will try look for the layout true.erb