1
0
Fork 0
mirror of https://github.com/heartcombo/devise.git synced 2022-11-09 12:18:31 -05:00

Update views generator and now have scoped views.

This commit is contained in:
José Valim 2010-02-17 12:25:20 +01:00
parent 5bf2eb3850
commit 02e8c04cde
36 changed files with 134 additions and 145 deletions

View file

@ -1,6 +1,12 @@
== 1.1.0
* Rails 3 compatibility
* enhancements
* Rails 3 compatibility.
* All controllers and views are namespaced, for example: Devise::SessionsController and "devise/sessions".
* deprecations
* Rails 3 compatible only.
* The scoped views are no longer "sessions/users/new". Now use "users/sessions/new".
== 1.0.1

View file

@ -175,7 +175,7 @@ Since devise is an engine, it has all default views inside the gem. They are goo
By default Devise will use the same views for all roles you have. But what if you need so different views to each of them? Devise also has an easy way to accomplish it: just setup config.scoped_views to true inside "config/initializers/devise.rb".
After doing so you will be able to have views based on the scope like 'sessions/users/new' and 'sessions/admin/new'. If no view is found within the scope, Devise will fallback to the default view.
After doing so you will be able to have views based on the scope like 'users/sessions/new' and 'admin/sessions/new'. If no view is found within the scope, Devise will fallback to the default view.
Devise uses flash messages to let users know if their login is successful or not. Devise expects your application to call 'flash[:notice]' and 'flash[:alert]' as appropriate.

View file

@ -1,4 +1,4 @@
class ConfirmationsController < ApplicationController
class Devise::ConfirmationsController < ApplicationController
include Devise::Controllers::InternalHelpers
# GET /resource/confirmation/new

View file

@ -1,4 +1,4 @@
class PasswordsController < ApplicationController
class Devise::PasswordsController < ApplicationController
include Devise::Controllers::InternalHelpers
before_filter :require_no_authentication

View file

@ -1,4 +1,4 @@
class RegistrationsController < ApplicationController
class Devise::RegistrationsController < ApplicationController
include Devise::Controllers::InternalHelpers
before_filter :require_no_authentication, :only => [ :new, :create ]

View file

@ -1,4 +1,4 @@
class SessionsController < ApplicationController
class Devise::SessionsController < ApplicationController
include Devise::Controllers::InternalHelpers
before_filter :require_no_authentication, :only => [ :new, :create ]

View file

@ -1,4 +1,4 @@
class UnlocksController < ApplicationController
class Devise::UnlocksController < ApplicationController
include Devise::Controllers::InternalHelpers
# GET /resource/unlock/new

View file

@ -1,13 +1,12 @@
class DeviseMailer < ::ActionMailer::Base
extend Devise::Controllers::InternalHelpers::ScopedViews
class Devise::Mailer < ::ActionMailer::Base
include Devise::Controllers::ScopedViews
attr_reader :devise_mapping, :resource
# Deliver confirmation instructions when the user is created or its email is
# updated, and also when confirmation is manually requested
def confirmation_instructions(record)
setup_mail(record, :confirmation_instructions)
end
# Deliver reset password instructions when manually requested
def reset_password_instructions(record)
setup_mail(record, :reset_password_instructions)
end
@ -19,27 +18,15 @@ class DeviseMailer < ::ActionMailer::Base
private
# Configure default email options
def setup_mail(record, key)
mapping = Devise::Mapping.find_by_class(record.class)
raise "Invalid devise resource #{record}" unless mapping
def setup_mail(record, action)
@devise_mapping = Devise::Mapping.find_by_class(record.class)
@resource = instance_variable_set("@#{mapping.name}", record)
raise "Invalid devise resource #{record}" unless @devise_mapping
@resource = instance_variable_set("@#{@devise_mapping.name}", record)
mail(:subject => translate(mapping, key), :from => mailer_sender(mapping),
:to => record.email) do |format|
format.html { render_with_scope(key, mapping) }
end
end
def render_with_scope(key, mapping)
if self.class.scoped_views
begin
render :template => "devise_mailer/#{mapping.as}/#{key}"
rescue ActionView::MissingTemplate
render :template => "devise_mailer/#{key}"
end
else
render :template => "devise_mailer/#{key}"
mail(:subject => translate(@devise_mapping, action),
:from => mailer_sender(@devise_mapping), :to => record.email) do |format|
format.html { render_with_scope(action, :controller => "mailer") }
end
end

View file

@ -9,4 +9,4 @@
<p><%= f.submit "Resend confirmation instructions" %></p>
<% end %>
<%= render :partial => "shared/devise_links" %>
<%= render :partial => "devise/shared/devise_links" %>

View file

@ -13,4 +13,4 @@
<p><%= f.submit "Change my password" %></p>
<% end %>
<%= render :partial => "shared/devise_links" %>
<%= render :partial => "devise/shared/devise_links" %>

View file

@ -9,4 +9,4 @@
<p><%= f.submit "Send me reset password instructions" %></p>
<% end %>
<%= render :partial => "shared/devise_links" %>
<%= render :partial => "devise/shared/devise_links" %>

View file

@ -22,4 +22,4 @@
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
<%= render :partial => "shared/devise_links" %>
<%= link_to "Back", :back %>

View file

@ -14,4 +14,4 @@
<p><%= f.submit "Sign up" %></p>
<% end -%>
<%= render :partial => "shared/devise_links" %>
<%= render :partial => "devise/shared/devise_links" %>

View file

@ -14,4 +14,4 @@
<p><%= f.submit "Sign in" %></p>
<% end -%>
<%= render :partial => "shared/devise_links" %>
<%= render :partial => "devise/shared/devise_links" %>

View file

@ -9,4 +9,4 @@
<p><%= f.submit "Resend unlock instructions" %></p>
<% end %>
<%= render :partial => "shared/devise_links" %>
<%= render :partial => "devise/shared/devise_links" %>

View file

@ -1,3 +0,0 @@
To copy all session, password, confirmation and mailer views from devise to your app just run the following command:
script/generate devise_views

View file

@ -1,21 +0,0 @@
class DeviseViewsGenerator < Rails::Generator::Base
def initialize(*args)
super
@source_root = options[:source] || File.join(spec.path, '..', '..')
end
def manifest
record do |m|
m.directory "app/views"
Dir[File.join(@source_root, "app", "views", "**/*.erb")].each do |file|
file = file.gsub(@source_root, "")[1..-1]
m.directory File.dirname(file)
m.file file, file
end
end
end
end

View file

@ -6,6 +6,7 @@ module Devise
module Controllers
autoload :Helpers, 'devise/controllers/helpers'
autoload :InternalHelpers, 'devise/controllers/internal_helpers'
autoload :ScopedViews, 'devise/controllers/scoped_views'
autoload :UrlHelpers, 'devise/controllers/url_helpers'
end

View file

@ -4,27 +4,18 @@ module Devise
# included in ApplicationController since they all depend on the url being
# accessed.
module InternalHelpers #:nodoc:
extend ActiveSupport::Concern
include Devise::Controllers::ScopedViews
def self.included(base)
base.class_eval do
extend ScopedViews
included do
helpers = [:resource, :scope_name, :resource_name,
:resource_class, :devise_mapping, :devise_controller?]
helper_method :resource, :scope_name, :resource_name, :resource_class, :devise_mapping, :devise_controller?
hide_action :resource, :scope_name, :resource_name, :resource_class, :devise_mapping, :devise_controller?
hide_action *helpers
helper_method *helpers
skip_before_filter *Devise.mappings.keys.map { |m| :"authenticate_#{m}!" }
before_filter :is_devise_resource?
end
end
module ScopedViews
def scoped_views
defined?(@scoped_views) ? @scoped_views : Devise.scoped_views
end
def scoped_views=(value)
@scoped_views = value
end
before_filter :is_devise_resource?
skip_before_filter *Devise.mappings.keys.map { |m| :"authenticate_#{m}!" }
end
# Gets the actual resource stored in the instance variable
@ -107,22 +98,6 @@ module Devise
set_flash_message(key, kind, true)
end
# Render a view for the specified scope. Turned off by default.
# Accepts just :controller as option.
def render_with_scope(action, options={})
controller_name = options.delete(:controller) || self.controller_name
if self.class.scoped_views
begin
render :template => "#{controller_name}/#{devise_mapping.as}/#{action}"
rescue ActionView::MissingTemplate
render :template => "#{controller_name}/#{action}"
end
else
render :template => "#{controller_name}/#{action}"
end
end
end
end
end

View file

@ -0,0 +1,35 @@
module Devise
module Controllers
module ScopedViews
extend ActiveSupport::Concern
module ClassMethods
def scoped_views
defined?(@scoped_views) ? @scoped_views : Devise.scoped_views
end
def scoped_views=(value)
@scoped_views = value
end
end
protected
# Render a view for the specified scope. Turned off by default.
# Accepts just :controller as option.
def render_with_scope(action, options={})
controller_name = options.delete(:controller) || self.controller_name
if self.class.scoped_views
begin
render :template => "#{devise_mapping.as}/#{controller_name}/#{action}"
rescue ActionView::MissingTemplate
render :template => "#{controller_path}/#{action}"
end
else
render :template => "#{controller_path}/#{action}"
end
end
end
end
end

View file

@ -57,7 +57,7 @@ module Devise
# Send confirmation instructions by email
def send_confirmation_instructions
::DeviseMailer.confirmation_instructions(self).deliver
::Devise::Mailer.confirmation_instructions(self).deliver
end
# Remove confirmation date and send confirmation instructions, to ensure

View file

@ -58,7 +58,7 @@ module Devise
# Send unlock instructions by email
def send_unlock_instructions
::DeviseMailer.unlock_instructions(self).deliver
::Devise::Mailer.unlock_instructions(self).deliver
end
# Resend the unlock instructions if the user is locked.

View file

@ -32,7 +32,7 @@ module Devise
# Resets reset password token and send reset password instructions by email
def send_reset_password_instructions
generate_reset_password_token!
::DeviseMailer.reset_password_instructions(self).deliver
::Devise::Mailer.reset_password_instructions(self).deliver
end
protected

View file

@ -96,35 +96,35 @@ module ActionDispatch::Routing
protected
def authenticatable(mapping)
scope(mapping.raw_path) do
get mapping.path_names[:sign_in], :to => "sessions#new", :as => :"new_#{mapping.name}_session"
post mapping.path_names[:sign_in], :to => "sessions#create", :as => :"#{mapping.name}_session"
get mapping.path_names[:sign_out], :to => "sessions#destroy", :as => :"destroy_#{mapping.name}_session"
scope mapping.raw_path do
get mapping.path_names[:sign_in], :to => "devise/sessions#new", :as => :"new_#{mapping.name}_session"
post mapping.path_names[:sign_in], :to => "devise/sessions#create", :as => :"#{mapping.name}_session"
get mapping.path_names[:sign_out], :to => "devise/sessions#destroy", :as => :"destroy_#{mapping.name}_session"
end
end
def recoverable(mapping)
scope(mapping.raw_path, :name_prefix => mapping.name) do
resource :password, :only => [:new, :create, :edit, :update], :as => mapping.path_names[:password]
scope mapping.raw_path, :name_prefix => mapping.name do
resource :password, :only => [:new, :create, :edit, :update], :as => mapping.path_names[:password], :controller => "devise/passwords"
end
end
def confirmable(mapping)
scope(mapping.raw_path, :name_prefix => mapping.name) do
resource :confirmation, :only => [:new, :create, :show], :as => mapping.path_names[:confirmation]
scope mapping.raw_path, :name_prefix => mapping.name do
resource :confirmation, :only => [:new, :create, :show], :as => mapping.path_names[:confirmation], :controller => "devise/confirmations"
end
end
def lockable(mapping)
scope(mapping.raw_path, :name_prefix => mapping.name) do
resource :unlock, :only => [:new, :create, :show], :as => mapping.path_names[:unlock]
scope mapping.raw_path, :name_prefix => mapping.name do
resource :unlock, :only => [:new, :create, :show], :as => mapping.path_names[:unlock], :controller => "devise/unlocks"
end
end
def registerable(mapping)
scope :name_prefix => mapping.name do
resource :registration, :only => [:new, :create, :edit, :update, :destroy], :as => mapping.raw_path[1..-1],
:path_names => { :new => mapping.path_names[:sign_up] }
:path_names => { :new => mapping.path_names[:sign_up] }, :controller => "devise/registrations"
end
end
end

View file

@ -23,7 +23,7 @@ module Devise
protected
def valid_controller?
params[:controller] == 'sessions'
params[:controller] =~ /sessions$/
end
def valid_params?

View file

@ -0,0 +1,11 @@
class DeviseViewsGenerator < Rails::Generators::Base
desc "Copies all Devise views to your application."
def self.source_root
@_devise_source_root ||= File.expand_path("../../../../app/views", __FILE__)
end
def copy_views
directory "devise"
end
end

View file

@ -221,15 +221,15 @@ class AuthenticationTest < ActionController::IntegrationTest
test 'renders the scoped view if turned on in an specific controller' do
begin
SessionsController.scoped_views = true
Devise::SessionsController.scoped_views = true
assert_raise Webrat::NotFoundError do
sign_in_as_user
end
assert_match /Special user view/, response.body
assert !PasswordsController.scoped_views
assert !Devise::PasswordsController.scoped_views
ensure
SessionsController.send :remove_instance_variable, :@scoped_views
Devise::SessionsController.send :remove_instance_variable, :@scoped_views
end
end

View file

@ -65,10 +65,10 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
test 'renders a scoped if scoped_views is set in the mailer class' do
begin
DeviseMailer.scoped_views = true
Devise::Mailer.scoped_views = true
assert_equal user.email, mail.body.decoded
ensure
DeviseMailer.send :remove_instance_variable, :@scoped_views
Devise::Mailer.send :remove_instance_variable, :@scoped_views
end
end

View file

@ -15,8 +15,6 @@ Rails::Application.routes.draw do
resources :admins, :only => [:index]
root :to => "home#index"
match '/admin_area/password/new', :to => "passwords#new"
match '/admin_area/home', :to => "admins#index", :as => :admin_root
match '/sign_in', :to => "sessions#new"
match '/sign_in', :to => "devise/sessions#new"
end

View file

@ -3,108 +3,108 @@ require 'test/test_helper'
class MapRoutingTest < ActionController::TestCase
test 'map new user session' do
assert_recognizes({:controller => 'sessions', :action => 'new'}, {:path => 'users/sign_in', :method => :get})
assert_recognizes({:controller => 'devise/sessions', :action => 'new'}, {:path => 'users/sign_in', :method => :get})
end
test 'map create user session' do
assert_recognizes({:controller => 'sessions', :action => 'create'}, {:path => 'users/sign_in', :method => :post})
assert_recognizes({:controller => 'devise/sessions', :action => 'create'}, {:path => 'users/sign_in', :method => :post})
end
test 'map destroy user session' do
assert_recognizes({:controller => 'sessions', :action => 'destroy'}, {:path => 'users/sign_out', :method => :get})
assert_recognizes({:controller => 'devise/sessions', :action => 'destroy'}, {:path => 'users/sign_out', :method => :get})
end
test 'map new user confirmation' do
assert_recognizes({:controller => 'confirmations', :action => 'new'}, 'users/confirmation/new')
assert_recognizes({:controller => 'devise/confirmations', :action => 'new'}, 'users/confirmation/new')
end
test 'map create user confirmation' do
assert_recognizes({:controller => 'confirmations', :action => 'create'}, {:path => 'users/confirmation', :method => :post})
assert_recognizes({:controller => 'devise/confirmations', :action => 'create'}, {:path => 'users/confirmation', :method => :post})
end
test 'map show user confirmation' do
assert_recognizes({:controller => 'confirmations', :action => 'show'}, {:path => 'users/confirmation', :method => :get})
assert_recognizes({:controller => 'devise/confirmations', :action => 'show'}, {:path => 'users/confirmation', :method => :get})
end
test 'map new user password' do
assert_recognizes({:controller => 'passwords', :action => 'new'}, 'users/password/new')
assert_recognizes({:controller => 'devise/passwords', :action => 'new'}, 'users/password/new')
end
test 'map create user password' do
assert_recognizes({:controller => 'passwords', :action => 'create'}, {:path => 'users/password', :method => :post})
assert_recognizes({:controller => 'devise/passwords', :action => 'create'}, {:path => 'users/password', :method => :post})
end
test 'map edit user password' do
assert_recognizes({:controller => 'passwords', :action => 'edit'}, 'users/password/edit')
assert_recognizes({:controller => 'devise/passwords', :action => 'edit'}, 'users/password/edit')
end
test 'map update user password' do
assert_recognizes({:controller => 'passwords', :action => 'update'}, {:path => 'users/password', :method => :put})
assert_recognizes({:controller => 'devise/passwords', :action => 'update'}, {:path => 'users/password', :method => :put})
end
test 'map new user unlock' do
assert_recognizes({:controller => 'unlocks', :action => 'new'}, 'users/unlock/new')
assert_recognizes({:controller => 'devise/unlocks', :action => 'new'}, 'users/unlock/new')
end
test 'map create user unlock' do
assert_recognizes({:controller => 'unlocks', :action => 'create'}, {:path => 'users/unlock', :method => :post})
assert_recognizes({:controller => 'devise/unlocks', :action => 'create'}, {:path => 'users/unlock', :method => :post})
end
test 'map show user unlock' do
assert_recognizes({:controller => 'unlocks', :action => 'show'}, {:path => 'users/unlock', :method => :get})
assert_recognizes({:controller => 'devise/unlocks', :action => 'show'}, {:path => 'users/unlock', :method => :get})
end
test 'map new user registration' do
assert_recognizes({:controller => 'registrations', :action => 'new'}, 'users/sign_up')
assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, 'users/sign_up')
end
test 'map create user registration' do
assert_recognizes({:controller => 'registrations', :action => 'create'}, {:path => 'users', :method => :post})
assert_recognizes({:controller => 'devise/registrations', :action => 'create'}, {:path => 'users', :method => :post})
end
test 'map edit user registration' do
assert_recognizes({:controller => 'registrations', :action => 'edit'}, {:path => 'users/edit', :method => :get})
assert_recognizes({:controller => 'devise/registrations', :action => 'edit'}, {:path => 'users/edit', :method => :get})
end
test 'map update user registration' do
assert_recognizes({:controller => 'registrations', :action => 'update'}, {:path => 'users', :method => :put})
assert_recognizes({:controller => 'devise/registrations', :action => 'update'}, {:path => 'users', :method => :put})
end
test 'map destroy user registration' do
assert_recognizes({:controller => 'registrations', :action => 'destroy'}, {:path => 'users', :method => :delete})
assert_recognizes({:controller => 'devise/registrations', :action => 'destroy'}, {:path => 'users', :method => :delete})
end
test 'map admin session with :as option' do
assert_recognizes({:controller => 'sessions', :action => 'new'}, {:path => 'admin_area/sign_in', :method => :get})
assert_recognizes({:controller => 'devise/sessions', :action => 'new'}, {:path => 'admin_area/sign_in', :method => :get})
end
test 'does not map admin confirmation' do
assert_raise ActionController::RoutingError do
assert_recognizes({:controller => 'confirmations', :action => 'new'}, 'admin_area/confirmation/new')
assert_recognizes({:controller => 'devise/confirmations', :action => 'new'}, 'admin_area/confirmation/new')
end
end
test 'map account with custom path name for session sign in' do
assert_recognizes({:controller => 'sessions', :action => 'new', :locale => 'en'}, '/en/accounts/login')
assert_recognizes({:controller => 'devise/sessions', :action => 'new', :locale => 'en'}, '/en/accounts/login')
end
test 'map account with custom path name for session sign out' do
assert_recognizes({:controller => 'sessions', :action => 'destroy', :locale => 'en'}, '/en/accounts/logout')
assert_recognizes({:controller => 'devise/sessions', :action => 'destroy', :locale => 'en'}, '/en/accounts/logout')
end
test 'map account with custom path name for password' do
assert_recognizes({:controller => 'passwords', :action => 'new', :locale => 'en'}, '/en/accounts/secret/new')
assert_recognizes({:controller => 'devise/passwords', :action => 'new', :locale => 'en'}, '/en/accounts/secret/new')
end
test 'map account with custom path name for confirmation' do
assert_recognizes({:controller => 'confirmations', :action => 'new', :locale => 'en'}, '/en/accounts/verification/new')
assert_recognizes({:controller => 'devise/confirmations', :action => 'new', :locale => 'en'}, '/en/accounts/verification/new')
end
test 'map account with custom path name for unlock' do
assert_recognizes({:controller => 'unlocks', :action => 'new', :locale => 'en'}, '/en/accounts/unblock/new')
assert_recognizes({:controller => 'devise/unlocks', :action => 'new', :locale => 'en'}, '/en/accounts/unblock/new')
end
test 'map account with custom path name for registration' do
assert_recognizes({:controller => 'registrations', :action => 'new', :locale => 'en'}, '/en/accounts/register')
assert_recognizes({:controller => 'devise/registrations', :action => 'new', :locale => 'en'}, '/en/accounts/register')
end
end