Two layouts for one controller

In the controller add this line

   layout :choose_layout

then add this method

   def choose_layout
     if action_name == 'login'
       return '2colwn'
       return '1col'

Of course, change it for your action and layout names.

You can also do
layout :some_layout, :only => [:new, :edit]
layout :some_other_layout, :except [:list, :show]

And of course at the end of your action you can just say
render :layout => 'something_else'


Hi Rohit,

Here's how I did it:

in application.rb

  def choose_layout
    if ['welcome'].include?(action_name)
    elsif !['welcome_xml', 'math_xml'].include?(action_name)

then in the controller

before_filter :choose_layout

I put the choose_layout filter last as there's no point in choosing a
layout if one of the other filters might fail. The local variable
action_name is actually a Rails provided global-ish variable, so you
don't need to set it yourself. If you have to make a decision
between actions that are named the same in multiple controllers, you
will also need to evaluate which controller is active. I have not
required that yet, so I don't know exactly how to do it. I would
like to think it's as easy as controller_name (to go along with
action_name), but I'm only guessing. In my testing, it was important
to return nil if I didn't want to use a layout, but I don't have an
API reference or any other documentation to prove that.

You can just as easily do an "if action_name == <some value>" instead
of using include?. At one time I had more than one action that was
using the 'one_column' layout and when I changed it, I didn't change
the conditional to a singleton test. I probably should as I expect a
simple equality test takes fewer processor cycles than include?.


I made a typo in my earlier post. Instead of

before_filter :choose_layout

I should have written

layout :choose_layout

Sorry if this caused any confusion.