Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

different layout for sign_in action in devise

I'm trying to use a different/custom layout named "devise" for the sign_in action. I found this page in the devise wiki, and the second example even says you can do it per-action (in this case, sign_in action), but it shows no example of doing that. Someone on IRC told me I could try this:

class ApplicationController < ActionController::Base
  protect_from_forgery

  layout :layout_by_resource

  def layout_by_resource
    if devise_controller? && resource_name == :user && action_name == 'sign_in'
      "devise"
    else
      "application"
    end
  end
end

But it does not seem to be working as it's still loading the default application layout. I would appreciate any help.

like image 659
Jorge Israel Peña Avatar asked Feb 13 '11 02:02

Jorge Israel Peña


3 Answers

Another way to apply custom layout for an action is as following.

According to How To: Create custom layouts "You can also set the layout for specific Devise controllers using a callback in config/environment.rb (rails 2) or config/application.rb (rails 3). This needs to be done in a to_prepare callback because it's executed once in production and before each request in development."

config.to_prepare do
    Devise::SessionsController.layout "devise"
    Devise::RegistrationsController.layout proc{ |controller| user_signed_in? ? "application"   : "devise" }
    Devise::ConfirmationsController.layout "devise"
    Devise::UnlocksController.layout "devise"            
    Devise::PasswordsController.layout "devise"        
end

Usually a layout distinction is made between pages behind login and pages which do not require authentication, so the above approach works most of the time. But I also experimented with using action_name helper to set a layout for a particular action and it worked like charm:

config.to_prepare do
    Devise::SessionsController.layout proc{ |controller| action_name == 'new' ? "devise"   : "application" }
end

I think this is the better and built in way to change the layout based on devise controller/action instead of creating a helper in ApplicationController.

like image 144
Zeeshan Avatar answered Oct 19 '22 23:10

Zeeshan


I just created app/views/layouts/devise/sessions.html.erb and put my layout in there.

like image 35
Josh Avatar answered Oct 20 '22 00:10

Josh


I figured it out, but I'll keep this question here in case other people are curious.

It was a stupid mistake. The fact is sign_in is the path, not the action. Looking at the relevant source, I can see that the required action is new, i.e., creating a new Devise Session. Changing my above code's conditional to:

if devise_controller? && resource_name == :user && action_name == 'new'

Works beautifully.

Hope that helps someone out there.

like image 45
Jorge Israel Peña Avatar answered Oct 20 '22 00:10

Jorge Israel Peña