2011-02-13 35 views
79

我试图为sign_in操作使用名为“设计”的不同/自定义布局。我在devise wiki中发现了this页面,第二个示例甚至说您可以按动作执行此操作(在这种情况下为sign_in操作),但它没有显示这样做的示例。有人在IRC告诉我,我可以试试这个:设计中的sign_in动作的不同布局

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 

但它似乎并没有工作,因为它仍然加载默认的应用程序布局。我将不胜感激任何帮助。

回答

43

我想通了,但如果其他人好奇,我会在这里保留这个问题。

这是一个愚蠢的错误。事实是sign_in是路径,不是的动作。查看relevant source,我看到所需的操作是new,即创建了新的设计会话。更改我的上述代码的条件为:

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

工作得很好。

希望能帮助那里的人。

+0

这不会适用于注册#new和session#new的布局吗? – Ayrad 2017-02-21 20:11:08

1

只要您不知道,您也可以使用rake routes来查看您的rails应用程序中的路线以及它们映射到的动作/控制器。

new_user_registration GET /accounts/sign_up(.:format)  {:action=>"new", :controller=>"devise/registrations"} 
edit_user_registration GET /accounts/edit(.:format)   {:action=>"edit", :controller=>"devise/registrations"} 
         PUT /accounts(.:format)    {:action=>"update", :controller=>"devise/registrations"} 
         DELETE /accounts(.:format)    {:action=>"destroy", :controller=>"devise/registrations"} 
+0

谢谢,我确实知道关于耙路线,我只是没有想过,'sign_in'可能不是实际行动的名称,我想它会是,然后我意识到它都围绕着这就是为什么它对应于新的行动。 – 2011-02-13 06:16:46

90

为动作应用自定义布局的另一种方法如下。

根据How To: Create custom layouts“您还可以在config/environment.rb(rails 2)或config/application.rb(rails 3)中使用回调来设置特定Devise控制器的布局,这需要在to_prepare回调,因为它在生产中和开发中的每个请求之前执行一次。“

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 

通常在登录页面和不需要认证的页面之间进行布局区分,所以上面的方法大多数时候都是有效的。但是,我也尝试过使用action_name帮手来设置特定的操作布局和它的工作般的魅力:

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

我觉得这是更好的和基于色器件控制器/动作而不是内置的方式来改变布局在ApplicationController中创建一个帮助器。

+3

另外,不要忘记每次在config文件夹中对任何文件进行更改时重新启动服务器,在这种情况下,config/application.rb for Rails3或config/environment.rb for Rails 2,以使更改生效。 – Zeeshan 2011-08-21 17:13:46

+0

**小心**我在rails 3.1中试过这种方法,它使资产文件夹中资源的加载速度明显变慢。这不会影响生产服务器,但是当您拥有多个css/js文件时,您会注意到它。 – Gazler 2012-02-17 16:55:18

+0

在上面的例子中,是否可以为单独的设计资源配置布局(例如,让我们假设我们有两种不同类型的设计用户,并且每个都需要它们自己的布局) – ckarbass 2012-06-30 01:37:23

61

我刚刚创建了app/views/layouts/devise/sessions.html.erb并将我的布局放在那里。

0

这里是一个班轮,谁想要都制定行动,以使用新的布局:

class ApplicationController < ActionController::Base 
    protect_from_forgery 

    layout Proc.new { |controller| controller.devise_controller? ? 'devise' : 'application' } 
end 
8

这是我做到了。如果用户必须登录,我想要一个不同的布局,但如果用户必须编辑他/她的个人资料,则需要不同的布局。

我正在使用Rails 4.1。1

在应用控制器,补充一点:

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 
5

惊讶地没有看到这个答案的任何地方,但你也可以这样做:

在routes.rb中,改变你的色器件的配置看是这样的:

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

然后在app /控制器/ sessions_controller.rb

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

如果您需要在任何Devise控制器中执行额外的逻辑覆盖,这将特别有用。

7

最简单的解决方案是在app/views/layouts文件夹中创建一个名为devise.html.haml的布局。而Rails的魔术则负责其余部分。

app/views/layouts/devise.html.haml