different layout for sign_in action in devise

后端 未结 8 2156
情深已故
情深已故 2020-12-02 05:12

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 pe

相关标签:
8条回答
  • 2020-12-02 05:27

    Surprised to not see this answer anywhere, but you can also do this:

    In routes.rb, change your devise config to look something like this:

      devise_for :users, controllers: {
        sessions: 'sessions'
      }
    

    Then in app/controllers/sessions_controller.rb

    class SessionsController < Devise::SessionsController
      layout 'devise', only: [:new]
    end
    

    This is especially useful if you need to do additional logic overrides in any of the Devise controllers.

    0 讨论(0)
  • 2020-12-02 05:31

    The by far simplest solution is to just create a layout called devise.html.haml in your app/views/layouts folder. and the Rails magic takes care of the rest.

    app/views/layouts/devise.html.haml
    
    0 讨论(0)
  • 2020-12-02 05:33

    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.

    0 讨论(0)
  • 2020-12-02 05:33

    This is how I did it. I wanted a different layout if the user had to sign in, but a different layout if the user had to edit his/her profile.

    I am using Rails 4.1.1

    In the application controller, add this :

    class ApplicationController < ActionController::Base
      # Prevent CSRF attacks by raising an exception.
      # For APIs, you may want to use :null_session instead.
      protect_from_forgery with: :exception
      before_action :configure_permitted_parameters, if: :devise_controller?
    
      layout :layout_by_resource
    
      # Define the permitted parameters for Devise.
      protected
    
      def configure_permitted_parameters
        devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:firstname, :lastname, :email, :password, :password_confirmation)}
        devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:avatar, :firstname, :lastname, :email, :password, :password_confirmation, :current_password) }
      end
    
      def layout_by_resource
        if devise_controller? and user_signed_in?
          'dashboard'
        else
          'application'
        end
      end
    end
    
    0 讨论(0)
  • 2020-12-02 05:35

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

    0 讨论(0)
  • 2020-12-02 05:41

    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.

    0 讨论(0)
提交回复
热议问题