Rails layouts per action?

Ruby on-Rails

Ruby on-Rails Problem Overview


I use a different layout for some actions (mostly for the new action in most of the controllers).

I am wondering what the best way to specify the layout would be? (I am using 3 or more different layouts in the same controller)

I don't like using

> render :layout => 'name'

I liked doing

> layout 'name', :only => [:new]

But I can't use that to specify 2 or more different layouts.

For example:

When I call layout 2 times in the same controller, with different layout names and different only options, the first one gets ignored - those actions don't display in the layout I specified.

Note: I'm using Rails 2.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

You can use a method to set the layout.

class MyController < ApplicationController
  layout :resolve_layout
  
  # ...
  
  private
  
  def resolve_layout
    case action_name
    when "new", "create"
      "some_layout"
    when "index"
      "other_layout"
    else
      "application"
    end
  end
end

Solution 2 - Ruby on-Rails

If you are only selecting between two layouts, you can use :only:

class ProductsController < ApplicationController
   layout "admin", only: [:new, :edit]
end

or

class ProductsController < ApplicationController
   layout "application", only: [:index]
end

Solution 3 - Ruby on-Rails

You can specify the layout for an individual action using respond_to:

  def foo
    @model = Bar.first
    respond_to do |format|
      format.html {render :layout => 'application'}
    end
  end

Solution 4 - Ruby on-Rails

You can also specify the layout for action using render:

def foo
  render layout: "application"
end

Solution 5 - Ruby on-Rails

There's a gem (layout_by_action) for that :)

layout_by_action [:new, :create] => "some_layout", :index => "other_layout"

https://github.com/barelyknown/layout_by_action

Solution 6 - Ruby on-Rails

Various ways to specify layout under controller:

  1. In following code, application_1 layout is called under index and show action of Users controller and application layout(default layout) is called for other actions.

     class UsersController < ApplicationController
       layout "application_1", only: [:index, :show]
     end
    
  2. In following code, application_1 layout is called for all action of Users controller.

     class UsersController < ApplicationController
        layout "application_1"
     end
    
  3. In following code, application_1 layout is called for test action of Users controllers only and for all other action application layout(default) is called.

         class UsersController < ApplicationController
           def test
             render layout: "application_1"
           end
         end
    

Solution 7 - Ruby on-Rails

Precision :

A not really but working DRY way is what you see above, but with a precision : the layout need to be after your variables for working ("@some"). As :

def your_action
   @some = foo
   render layout: "your_layout"
end

And not :

def your_action
   render layout: "your_layout"
   @some = foo
   @foo = some
end

If you do a before_action... it's won't work also.

Hope it helps.

Solution 8 - Ruby on-Rails

You can use it like my example:

def show
...
render layout: "empty",template: "admin/orders/print" if params.key?('print')
end

I specified the layout and the template html.erb if params print present.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmrbrdoView Question on Stackoverflow
Solution 1 - Ruby on-RailsAugust LilleaasView Answer on Stackoverflow
Solution 2 - Ruby on-RailsaxeltagliaView Answer on Stackoverflow
Solution 3 - Ruby on-RailsGavin TerrillView Answer on Stackoverflow
Solution 4 - Ruby on-RailsyottanamiView Answer on Stackoverflow
Solution 5 - Ruby on-RailsbarelyknownView Answer on Stackoverflow
Solution 6 - Ruby on-Railspuneet18View Answer on Stackoverflow
Solution 7 - Ruby on-RailsGregdebrickView Answer on Stackoverflow
Solution 8 - Ruby on-RailsramzieusView Answer on Stackoverflow