开发者

Rails layouts per action?

I us开发者_Go百科e 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.


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


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


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


You can also specify the layout for action using render:

def foo
  render layout: "application"
end


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


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
    


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜