radiant-reader-extension 3.0.20 → 3.0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/README.md +12 -33
  2. data/app/controllers/admin/group_invitations_controller.rb +4 -12
  3. data/app/controllers/admin/memberships_controller.rb +2 -2
  4. data/app/controllers/reader_activations_controller.rb +1 -1
  5. data/app/controllers/reader_sessions_controller.rb +1 -1
  6. data/app/helpers/reader_helper.rb +3 -3
  7. data/app/models/reader.rb +20 -15
  8. data/app/models/reader_page.rb +1 -1
  9. data/app/models/reader_session.rb +1 -1
  10. data/app/views/accounts/_controls.html.haml +1 -1
  11. data/app/views/accounts/_edit_names.html.haml +21 -0
  12. data/app/views/accounts/_form.html.haml +1 -21
  13. data/app/views/accounts/_profile_form.html.haml +8 -12
  14. data/app/views/accounts/edit.html.haml +1 -1
  15. data/app/views/accounts/edit_profile.html.haml +1 -1
  16. data/app/views/admin/group_invitations/new.html.haml +2 -2
  17. data/app/views/admin/group_invitations/preview.html.haml +5 -10
  18. data/app/views/admin/memberships/_reader.html.haml +1 -1
  19. data/app/views/admin/messages/_help.html.haml +3 -2
  20. data/app/views/admin/messages/show.html.haml +1 -1
  21. data/app/views/admin/reader_configuration/edit.html.haml +3 -1
  22. data/app/views/admin/reader_configuration/show.html.haml +3 -1
  23. data/app/views/admin/readers/_form.html.haml +14 -15
  24. data/app/views/admin/readers/edit.html.haml +1 -1
  25. data/app/views/admin/readers/index.html.haml +9 -7
  26. data/app/views/admin/readers/remove.html.haml +1 -1
  27. data/app/views/dashboard/_welcome.html.haml +2 -2
  28. data/app/views/groups/_group.html.haml +1 -1
  29. data/app/views/memberships/_membership.html.haml +2 -2
  30. data/app/views/password_resets/edit.html.haml +1 -1
  31. data/app/views/reader_activations/show.html.haml +1 -1
  32. data/app/views/readers/_description.html.haml +1 -1
  33. data/app/views/readers/_directory.html.haml +6 -0
  34. data/app/views/readers/_mugshot.html.haml +2 -2
  35. data/app/views/readers/_profile.html.haml +1 -1
  36. data/app/views/readers/_reader.html.haml +2 -2
  37. data/app/views/readers/show.html.haml +5 -4
  38. data/config/initializers/radiant_config.rb +2 -0
  39. data/config/locales/en.yml +12 -4
  40. data/db/migrate/003_reader_honorifics.rb +0 -1
  41. data/db/migrate/20111013134949_sort_out_names.rb +13 -0
  42. data/db/migrate/20111013203306_remove_login.rb +14 -0
  43. data/lib/radiant-reader-extension.rb +1 -1
  44. data/lib/reader_admin_ui.rb +1 -1
  45. data/lib/reader_tags.rb +2 -2
  46. data/lib/reader_user.rb +0 -1
  47. data/public/stylesheets/sass/reader.sass +8 -0
  48. data/radiant-reader-extension-3.1.0.gem +0 -0
  49. data/spec/controllers/accounts_controller_spec.rb +1 -1
  50. data/spec/datasets/readers_dataset.rb +1 -4
  51. data/spec/lib/reader_tags_spec.rb +3 -3
  52. data/spec/models/reader_spec.rb +19 -13
  53. data/spec/spec.opts +1 -1
  54. metadata +8 -4
data/README.md CHANGED
@@ -14,7 +14,7 @@ Multi-site compatibility is currently missing but will follow as soon as I can a
14
14
 
15
15
  ## Note on internationalisation and customisation
16
16
 
17
- The locale strings here are generally defined in a functional rather than grammatical way. That is, they have labels like `activation_required_explanation` rather than being assembled out of lexical units. This is partly because for flexibility of translation, but also because it gives you an easy way to change the text on functional pages like reader-preferences and registration forms.
17
+ The locale strings here are generally defined in a functional rather than grammatical way. That is, they have labels like `activation_required_explanation` rather than being assembled out of lexical units. This is partly for flexibility of translation, but also because it gives you an easy way to change the text on functional pages like reader-preferences and registration forms.
18
18
 
19
19
  ## Requirements
20
20
 
@@ -31,13 +31,12 @@ Install the gem:
31
31
  add it to your application's Gemfile:
32
32
 
33
33
  gem 'authlogic', "~> 2.1.6"
34
- gem radiant-reader-extension, '~>2.0.0'
34
+ gem radiant-reader-extension, '~>3.1.0'
35
35
 
36
36
  and then you can bring over assets and create data tables:
37
37
 
38
- rake radiant:extensions:update_all
39
- rake radiant:extensions:reader:migrate
40
38
  rake radiant:extensions:reader:update
39
+ rake radiant:extensions:reader:migrate
41
40
 
42
41
  ## Configuration
43
42
 
@@ -47,8 +46,7 @@ All the main configuration settings can now be managed through the `settings > r
47
46
 
48
47
  This is primarily a framework and its main purpose is to take care of the dull minutiae of account-management. The basic reader framework provides for:
49
48
 
50
- * registration
51
- * honeypot spam trap
49
+ * registration with honeypot spam trap
52
50
  * activation by email confirmation
53
51
  * logging in and out
54
52
  * password reminders
@@ -58,6 +56,10 @@ This is primarily a framework and its main purpose is to take care of the dull m
58
56
  * configurable members directory with csv and vcard export
59
57
  * administrative email messages for welcome, invitation, etc
60
58
  * ad-hoc email messages to some or all readers
59
+ * group-membership
60
+ * group-based access control
61
+ * group-based messaging
62
+ * configurable directory service
61
63
 
62
64
  ## Reader groups
63
65
 
@@ -78,7 +80,7 @@ For more reader-facing usefulness please see our [forum extension](http://github
78
80
 
79
81
  ## Layouts
80
82
 
81
- We use the `layouts` extension to wrap the appearance of your public site around the views produced by the reader extension. You can configure this with the dropdown list on the reader configuration page.
83
+ We use the `layouts` extension to wrap the appearance of your public site around the views produced by the reader extension. You can select a layout with the dropdown list on the reader configuration page.
82
84
 
83
85
  The laying-out is achieved by defining lots of fake page parts in the reader views. All your layout has to do is include those page parts with the usual `<r:content />` calls.
84
86
 
@@ -107,9 +109,9 @@ Some standard formatting and interaction is included for you to build upon.
107
109
  `/stylesheets/sass/reader.sass` includes the default formatting of reader-facing forms and lists. It could probably stand to be reorganised a bit but you should find it a useful starting point and I recommend that you override it selectively rather than replacing it completely. There are two ways to do that:
108
110
 
109
111
  * @import 'reader.sass' at the top of your (SASS-based) stylesheet within radiant
110
- * link to /stylesheets/reader.css in the old-fashioned way and then bring in your own stylesheets any way you like.
112
+ * link to /stylesheets/reader.css in the old-fashioned way and then bring in your own stylesheets afterwards.
111
113
 
112
- Or you can replace all this with your own, of course.
114
+ Or you can replace the whole lot with your own recipe, of course.
113
115
 
114
116
  ## ReaderPages
115
117
 
@@ -130,30 +132,7 @@ All the reader pages (both public and administrative) are sharded in the AdminUI
130
132
 
131
133
  Most of your reader-facing controllers will want to inherit from `ReaderActionController`.
132
134
 
133
- Marking a reader as untrusted does nothing here apart from making them go red, but we assume that in other extensions it will have some limiting effect.
134
-
135
- ## Latest changes
136
-
137
- This version requires edge radiant, or radiant 1 when it becomes available.
138
-
139
- New ReaderPages provide flexible directory services with configurable access control. The old controller and page parts mechanism is likely to be phased out gradually both here and in the forum in favour of more orthodox radiant page-types. We will always need to use the layout-wrapper approach for login and registration forms, though.
140
-
141
- Right now we are **not compatible with multi_site or the sites extension**: that's mostly because neither is radiant edge: it will all be sorted out in time for the release of v1, which isn't far away.
142
-
143
- Also:
144
-
145
- * groups hierarchical
146
- * public interface internationalized;
147
- * Uses the new configuration interface;
148
- * Messaging much simplified and now intended to be purely administrative.
149
- * ajaxable status panel returned by `reader_session_url` (ie. you just have to call /reader_session.js over xmlhttp to get a sensible welcome and control block)
150
-
151
- ## See also
152
-
153
- * [reader_group](http://github.com/spanner/radiant-reader_group-extension)
154
- * [downloads](http://github.com/spanner/radiant-downloads-extension)
155
- * [forum](http://github.com/spanner/radiant-forum-extension)
156
- * [group_forum](http://github.com/spanner/radiant-group_forum-extension)
135
+ Marking a reader as untrusted does nothing here apart from making them go red, but in the forum it prevents participation and we assume that in other extensions it will have a similar limiting effect.
157
136
 
158
137
  ## Bugs and comments
159
138
 
@@ -57,22 +57,14 @@ private
57
57
  CSV::StringReader.parse(readerdata).each do |line|
58
58
  csv = line.collect {|value| value ? value.gsub(/^ */, '').chomp : ''}
59
59
  input = {}
60
- input[:honorific] = csv.shift if Radiant::Config['reader.use_honorifics?']
61
- [:name, :email, :login, :phone].each {|field| input[field] = csv.shift}
60
+ input[:honorific] = csv.shift if Radiant::Config['reader.show_honorifics?']
61
+ [:name, :email, :phone].each {|field| input[field] = csv.shift}
62
62
  r = Reader.find_by_email(input[:email]) || Reader.new(input)
63
- r.create_password! #only for validation purposes: not saved not passed through
64
- r.login = generate_login(input[:name]) if r.login.blank?
65
- r.valid? # so that errors can be shown on the confirmation form
63
+ r.create_password! # only for validation purposes: not saved nor passed through
64
+ r.valid? # so that errors can be shown on the confirmation form
66
65
  readers << r
67
66
  end
68
67
  readers
69
68
  end
70
69
 
71
- def generate_login(name)
72
- names = name.split
73
- initials = names.map {|n| n.slice(0,1)}
74
- initials.pop
75
- initials.push(names.last).join('_').downcase
76
- end
77
-
78
70
  end
@@ -10,7 +10,7 @@ class Admin::MembershipsController < ApplicationController
10
10
  @membership = Membership.find_or_create_by_reader_id_and_group_id(@reader.id, @group.id)
11
11
  respond_to do |format|
12
12
  format.html {
13
- flash[:notice] = "#{@reader.name} added to group #{@group.name}"
13
+ flash[:notice] = "#{@reader.preferred_name} added to group #{@group.name}"
14
14
  redirect_to admin_group_url(@group)
15
15
  }
16
16
  format.js { render :partial => 'reader' }
@@ -23,7 +23,7 @@ class Admin::MembershipsController < ApplicationController
23
23
  @membership.delete if @membership
24
24
  respond_to do |format|
25
25
  format.html {
26
- flash[:notice] = "#{@reader.name} removed from group #{@group.name}" if @membership
26
+ flash[:notice] = "#{@reader.preferred_name} removed from group #{@group.name}" if @membership
27
27
  redirect_to admin_group_url(@group)
28
28
  }
29
29
  format.js { render :partial => 'reader' }
@@ -48,7 +48,7 @@ protected
48
48
 
49
49
  def check_reader_inactive
50
50
  if @reader && @reader.activated?
51
- flash[:notice] = t('reader_extension.hello').titlecase + " #{@reader.name}! " + t('reader_extension.already_active')
51
+ flash[:notice] = t('reader_extension.hello').titlecase + " #{@reader.preferred_name}! " + t('reader_extension.already_active')
52
52
  redirect_back_or_to default_welcome_url(@reader)
53
53
  false
54
54
  end
@@ -47,7 +47,7 @@ class ReaderSessionsController < ReaderActionController
47
47
  end
48
48
  respond_to do |format|
49
49
  format.html {
50
- flash[:notice] = t('reader_extension.hello').titlecase + " #{@reader_session.reader.name}. " + t('reader_extension.welcome_back')
50
+ flash[:notice] = t('reader_extension.hello').titlecase + " #{@reader_session.reader.preferred_name}. " + t('reader_extension.welcome_back')
51
51
  redirect_back_or_to default_welcome_url(@reader_session.reader)
52
52
  }
53
53
  format.js {
@@ -17,7 +17,7 @@ module ReaderHelper
17
17
  size = gravatar_options[:size] || 40
18
18
  img_options[:size] ||= "#{size}x#{size}"
19
19
  gravatar_options[:default] ||= "#{request.protocol}#{request.host_with_port}/images/furniture/no_gravatar.png"
20
- img_options[:alt] ||= reader.name if reader
20
+ img_options[:alt] ||= reader.preferred_name if reader
21
21
  if reader.nil? || reader.email.blank?
22
22
  image_tag gravatar_options[:default], img_options
23
23
  else
@@ -88,11 +88,11 @@ module ReaderHelper
88
88
  def message_preview(subject, body, reader)
89
89
  preview = <<EOM
90
90
  From: #{current_user.name} &lt;#{current_user.email}&gt;
91
- To: #{reader.name} &lt;#{reader.email}&gt;
91
+ To: #{reader.preferred_name} &lt;#{reader.email}&gt;
92
92
  Date: #{Time.now.to_date.to_s :long}
93
93
  <strong>Subject: #{subject}</strong>
94
94
 
95
- Dear #{reader.name},
95
+ Dear #{reader.preferred_name},
96
96
 
97
97
  #{body}
98
98
 
@@ -5,7 +5,7 @@ require 'vcard'
5
5
  require "fastercsv"
6
6
 
7
7
  class Reader < ActiveRecord::Base
8
- @@user_columns = %w{name email login created_at password password_confirmation notes}
8
+ @@user_columns = %w{name email created_at password password_confirmation notes}
9
9
  cattr_accessor :user_columns
10
10
  cattr_accessor :current
11
11
  attr_accessor :email_field, :newly_activated, :skip_user_update
@@ -29,12 +29,14 @@ class Reader < ActiveRecord::Base
29
29
  has_many :groups, :through => :memberships, :uniq => true
30
30
  accepts_nested_attributes_for :memberships
31
31
 
32
- validates_presence_of :name, :email
33
- validates_length_of :name, :maximum => 100, :allow_nil => true
32
+ before_validation :combine_names
33
+
34
+ validates_presence_of :name, :forename, :surname, :email
35
+ validates_uniqueness_of :nickname, :allow_blank => true
36
+ validates_length_of :name, :forename, :surname, :maximum => 100, :allow_nil => false
34
37
  validates_length_of :password, :minimum => 5, :allow_nil => false, :unless => :existing_reader_keeping_password?
35
38
  # validates_format_of :password, :with => /[^A-Za-z]/, :unless => :existing_reader_keeping_password? # we have to match radiant so that users can log in both ways
36
39
  validates_confirmation_of :password, :unless => :existing_reader_keeping_password?
37
- validates_uniqueness_of :login, :allow_blank => true
38
40
  validate :email_must_not_be_in_use
39
41
 
40
42
  include RFC822
@@ -65,8 +67,8 @@ class Reader < ActiveRecord::Base
65
67
  }
66
68
  }
67
69
 
68
- def self.find_by_login_or_email(login_or_email)
69
- reader = find(:first, :conditions => ["login = ? OR email = ?", login_or_email, login_or_email])
70
+ def self.find_by_nickname_or_email(nickname_or_email)
71
+ reader = find(:first, :conditions => ["nickname = ? OR email = ?", nickname_or_email, nickname_or_email])
70
72
  end
71
73
 
72
74
  def self.for_user(user)
@@ -149,15 +151,10 @@ class Reader < ActiveRecord::Base
149
151
  groups.any?
150
152
  end
151
153
 
152
- # not very i18nal, this
153
- def forename
154
- read_attribute(:forename) || name.split(/\s+/).first
155
- end
156
-
157
- def surname
158
- read_attribute(:surname) || name.split(/\s+/).last
154
+ def preferred_name
155
+ nickname? ? nickname : name
159
156
  end
160
-
157
+
161
158
  def postal_address?
162
159
  !post_line1.blank? && !post_city.blank?
163
160
  end
@@ -287,6 +284,15 @@ class Reader < ActiveRecord::Base
287
284
 
288
285
  private
289
286
 
287
+ def combine_names
288
+ if self.name?
289
+ self.forename ||= self.name.split(/\s+/).first
290
+ self.surname ||= self.name.split(/\s+/).last
291
+ else
292
+ self.name = "#{self.forename} #{self.surname}"
293
+ end
294
+ end
295
+
290
296
  def email_must_not_be_in_use
291
297
  reader = Reader.find_by_email(self.email)
292
298
  user = User.find_by_email(self.email)
@@ -319,7 +325,6 @@ private
319
325
  if att['password']
320
326
  att["clear_password"] = att["password_confirmation"] = att["password"]
321
327
  end
322
- p "updating reader attributes with #{att.inspect}"
323
328
  self.update_attributes(att)
324
329
  self.skip_user_update = false
325
330
  end
@@ -51,7 +51,7 @@ class ReaderPage < Page
51
51
  self.reader = Reader.find_by_id(params.last) if params.last !~ /\D/
52
52
 
53
53
  raise ReaderError::AccessDenied, "Group visibility denied" if group && !group.visible_to?(current_reader)
54
- raise ReaderError::AccessDenied, "Reader visibility denied: #{current_reader} (#{current_reader.name}) cannot see #{reader} (#{reader.name})" if reader && !reader.visible_to?(current_reader)
54
+ raise ReaderError::AccessDenied, "Reader visibility denied: #{current_reader} (#{current_reader.preferred_name}) cannot see #{reader} (#{reader.preferred_name})" if reader && !reader.visible_to?(current_reader)
55
55
  raise ActiveRecord::RecordNotFound if reader && group && !reader.has_group?(group)
56
56
 
57
57
  self
@@ -1,3 +1,3 @@
1
1
  class ReaderSession < Authlogic::Session::Base
2
- find_by_login_method :find_by_login_or_email
2
+ find_by_login_method :find_by_nickname_or_email
3
3
  end
@@ -2,7 +2,7 @@
2
2
  = t('reader_extension.navigation.welcome_please_log_in', :login_url => reader_login_url, :register_url => new_reader_url)
3
3
  - else
4
4
  %strong
5
- = link_to t('reader_extension.navigation.greeting', :name => current_reader.name), reader_profile_url
5
+ = link_to t('reader_extension.navigation.greeting', :name => current_reader.preferred_name), reader_profile_url
6
6
  - if !current_reader.activated?
7
7
  = link_to t('reader_extension.navigation.activate'), reader_activation_url
8
8
  - else
@@ -0,0 +1,21 @@
1
+ %p
2
+ %span.semi
3
+ = f.label :forename, nil, :class => 'required'
4
+ %br
5
+ = f.text_field :forename, :class => 'standard'
6
+ %br
7
+ %span.formnote= t('reader_extension.form_notes.account.forename')
8
+
9
+ %span.semi
10
+ = f.label :surname, nil, :class => 'required'
11
+ %br
12
+ = f.text_field :surname, :class => 'standard'
13
+ %br
14
+ %span.formnote= t('reader_extension.form_notes.account.surname')
15
+
16
+ %p.nickname.clear
17
+ = f.label :nickname, nil, :class => 'optional'
18
+ %br
19
+ = f.text_field :nickname, :class => 'standard'
20
+ %br
21
+ %span.formnote= t('reader_extension.form_notes.account.nickname')
@@ -4,12 +4,7 @@
4
4
  - form_for reader, :html => {:class => 'friendly'} do |f|
5
5
  %input{:type => :hidden, :name => :authentication_type, :value => :user}
6
6
 
7
- %p
8
- = f.label :name, nil, :class => 'required'
9
- %br
10
- = f.text_field :name, :class => 'standard'
11
- %br
12
- %span.formnote= t('reader_extension.form_notes.account.name')
7
+ = render :partial => 'edit_names', :locals => {:f => f}
13
8
 
14
9
  - if reader.new_record?
15
10
  %p
@@ -34,13 +29,6 @@
34
29
  %br
35
30
  %span.formnote= t('reader_extension.form_notes.account.email')
36
31
 
37
- %p
38
- = f.label :login, nil, :class => 'optional'
39
- %br
40
- = f.text_field :login, :class => 'standard'
41
- %br
42
- %span.formnote= t('reader_extension.form_notes.account.login')
43
-
44
32
  - if reader.new_record?
45
33
  %p
46
34
  = f.label :password, nil, :class => 'required'
@@ -73,14 +61,6 @@
73
61
  %br
74
62
  = f.password_field :password_confirmation, :class => 'standard', :autocomplete => 'off'
75
63
 
76
- - unless reader.new_record?
77
- %p
78
- = f.label :description, nil, :class => 'optional'
79
- %br
80
- = f.text_area :description, :class => 'standard'
81
- %br
82
- %span.formnote= t('reader_extension.form_notes.account.description')
83
-
84
64
  = render :partial => 'choose_memberships'
85
65
 
86
66
  %p
@@ -4,19 +4,14 @@
4
4
  - form_for reader, :html => {:class => 'friendly'} do |f|
5
5
  %input{:type => :hidden, :name => :authentication_type, :value => :user}
6
6
 
7
- - if Radiant.config['reader.use_honorifics?']
7
+ - if Radiant.config['reader.show_honorifics?']
8
8
  %p
9
9
  = f.label :honorific, nil, :class => 'optional'
10
10
  %br
11
11
  = f.text_field :honorific, :class => 'standard'
12
12
  %span.formnote= t('reader_extension.form_notes.account.honorific')
13
13
 
14
- %p
15
- = f.label :email, nil, :class => 'required'
16
- %br
17
- = f.text_field :email, :class => 'standard'
18
- %br
19
- %span.formnote= t('reader_extension.form_notes.account.email')
14
+ = render :partial => 'edit_names', :locals => {:f => f}
20
15
 
21
16
  %p
22
17
  = f.label :phone, nil, :class => 'optional'
@@ -59,11 +54,12 @@
59
54
  = f.label :postcode, nil, :class => 'optional'
60
55
  = f.text_field :postcode, :class => 'standard'
61
56
 
62
- %p
63
- = f.label :description, nil, :class => 'optional'
64
- %br
65
- = f.text_area :description, :class => Radiant.config['forum.toolbar?'] ? 'rte' : 'standard'
66
- %span.formnote= t('reader_extension.form_notes.account.description')
57
+ - if Radiant.config['reader.show_descriptions?']
58
+ %p
59
+ = f.label :description, nil, :class => 'optional'
60
+ %br
61
+ = f.text_area :description, :class => Radiant.config['forum.toolbar?'] ? 'rte' : 'standard'
62
+ %span.formnote= t('reader_extension.form_notes.account.description')
67
63
 
68
64
  %p
69
65
  = f.check_box :unshareable, :class => 'reversed'
@@ -1,7 +1,7 @@
1
1
  - content_for :introduction do
2
2
  %p
3
3
  = t("reader_extension.hello").titlecase
4
- = link_to(@reader.name, reader_url(@reader)) + '.'
4
+ = link_to(@reader.preferred_name, reader_url(@reader)) + '.'
5
5
  = t('reader_extension.preferences_intro')
6
6
 
7
7
  - content_for :breadcrumbs do
@@ -1,7 +1,7 @@
1
1
  - content_for :introduction do
2
2
  %p
3
3
  = t("reader_extension.hello").titlecase
4
- = link_to(@reader.name, reader_url(@reader)) + '.'
4
+ = link_to(@reader.preferred_name, reader_url(@reader)) + '.'
5
5
  = t("reader_extension.profile_intro_#{Radiant.config['reader.directory_visibility']}")
6
6
 
7
7
  - content_for :breadcrumbs do
@@ -11,9 +11,9 @@
11
11
  %label{:for => "readerlist"}
12
12
  List of people
13
13
  %span.formnote
14
- - if Radiant::Config['reader.use_honorifics?']
14
+ - if Radiant::Config['reader.show_honorifics?']
15
15
  title or rank,
16
- name, email, [login], [phone]
16
+ name, email, [phone]
17
17
  = text_area_tag "readerlist", params[:readerlist], :class => "textarea", :style => "width: 100%; height: 240px;"
18
18
 
19
19
  %p.buttons
@@ -11,11 +11,10 @@
11
11
  %thead
12
12
  %tr
13
13
  %th
14
- - if Radiant::Config['reader.use_honorifics?']
14
+ - if Radiant::Config['reader.show_honorifics?']
15
15
  %th= t('reader_extension.honorific')
16
16
  %th= t('reader_extension.full_name')
17
17
  %th= t('reader_extension.email')
18
- %th= t('reader_extension.optional_login')
19
18
  %th= t('reader_extension.optional_phone')
20
19
  %tbody
21
20
  - i = 0
@@ -24,30 +23,26 @@
24
23
  %tr.import
25
24
  %td
26
25
  = check_box_tag "import_reader[]", i, reader.valid?
27
- - if Radiant::Config['reader.use_honorifics?']
26
+ - if Radiant::Config['reader.show_honorifics?']
28
27
  %td
29
28
  = text_field_tag "reader_#{i}[honorific]", reader.honorific, :class => "preview#{ ' with_error' if reader.errors.on(:honorific)}", :title => reader.errors.on(:honorific)
30
29
  %td
31
- = text_field_tag "reader_#{i}[name]", reader.name, :class => "preview#{ ' with_error' if reader.errors.on(:name)}", :title => reader.errors.on(:name)
30
+ = text_field_tag "reader_#{i}[name]", reader.preferred_name, :class => "preview#{ ' with_error' if reader.errors.on(:name)}", :title => reader.errors.on(:name)
32
31
  %td
33
32
  = text_field_tag "reader_#{i}[email]", reader.email, :class => "preview#{ ' with_error' if reader.errors.on(:email)}", :title => reader.errors.on(:email)
34
- %td
35
- = text_field_tag "reader_#{i}[login]", reader.login, :class => "preview#{ ' with_error' if reader.errors.on(:login)}", :title => reader.errors.on(:login)
36
33
  %td
37
34
  = text_field_tag "reader_#{i}[phone]", reader.phone, :class => "preview#{ ' with_error' if reader.errors.on(:phone)}", :title => reader.errors.on(:phone)
38
35
  - else
39
36
  %tr.invite
40
37
  %td
41
38
  = check_box_tag "invite_reader[]", reader.id, {:checked => true}
42
- - if Radiant::Config['reader.use_honorifics?']
39
+ - if Radiant::Config['reader.show_honorifics?']
43
40
  %td
44
41
  = text_field_tag "reader_#{i}[honorific]", reader.honorific, :class => "preview#{ ' with_error' if reader.errors.on(:honorific)}", :title => reader.errors.on(:honorific), :disabled => true
45
42
  %td
46
- = text_field_tag "reader_#{i}[name]", reader.name, :class => "preview#{ ' with_error' if reader.errors.on(:name)}", :title => reader.errors.on(:name), :disabled => true
43
+ = text_field_tag "reader_#{i}[name]", reader.preferred_name, :class => "preview#{ ' with_error' if reader.errors.on(:name)}", :title => reader.errors.on(:name), :disabled => true
47
44
  %td
48
45
  = text_field_tag "reader_#{i}[email]", reader.email, :class => "preview#{ ' with_error' if reader.errors.on(:email)}", :title => reader.errors.on(:email), :disabled => true
49
- %td
50
- = text_field_tag "reader_#{i}[login]", reader.login, :class => "preview#{ ' with_error' if reader.errors.on(:login)}", :title => reader.errors.on(:login), :disabled => true
51
46
  %td
52
47
  = text_field_tag "reader_#{i}[phone]", reader.phone, :class => "preview#{ ' with_error' if reader.errors.on(:phone)}", :title => reader.errors.on(:phone), :disabled => true
53
48
  - i = i + 1
@@ -3,7 +3,7 @@
3
3
  - membership = reader.membership_of(group)
4
4
  - cssclass = membership ? "fake_checkbox checked" : "fake_checkbox unchecked"
5
5
 
6
- = link_to reader.name, toggle_admin_membership_url(:group_id => group.id, :reader_id => reader.id), {:class => cssclass, :id => "toggle_reader_#{reader.id}"}
6
+ = link_to reader.preferred_name, toggle_admin_membership_url(:group_id => group.id, :reader_id => reader.id), {:class => cssclass, :id => "toggle_reader_#{reader.id}"}
7
7
  - if membership
8
8
  %span.role
9
9
  = render :partial => 'admin/memberships/role', :locals => {:membership => membership, :group => group}
@@ -37,5 +37,6 @@
37
37
  %li
38
38
  %code &lt;r:recipient:activation_url /&gt;
39
39
  is the address that will activate a newly-created account
40
- %li
41
- %code &lt;r:recipient:description /&gt;
40
+ - if Radiant.config['reader.show_descriptions?']
41
+ %li
42
+ %code &lt;r:recipient:description /&gt;
@@ -80,7 +80,7 @@
80
80
  %li
81
81
  = check_box_tag "recipients[]", reader.id, false, :id => "recipients_#{reader.id}", :class => 'toggled'
82
82
  %label.checkbox
83
- = reader.name
83
+ = reader.preferred_name
84
84
 
85
85
  %p.buttons
86
86
  = submit_tag t('reader_extension.send_message')
@@ -21,7 +21,9 @@
21
21
  %p
22
22
  = edit_config('reader.get_profile?')
23
23
  %p
24
- = edit_config('reader.use_honorifics?')
24
+ = edit_config('reader.show_honorifics?')
25
+ %p
26
+ = edit_config('reader.show_descriptions?')
25
27
  %p
26
28
  = edit_config('reader.layout')
27
29
 
@@ -17,7 +17,9 @@
17
17
  %p.ruled
18
18
  = show_config 'reader.get_profile?'
19
19
  %p.ruled
20
- = show_config 'reader.use_honorifics?'
20
+ = show_config 'reader.show_honorifics?'
21
+ %p.ruled
22
+ = show_config 'reader.show_descriptions?'
21
23
  %p.ruled
22
24
  = show_config 'reader.layout'
23
25
  %p.ruled
@@ -5,33 +5,32 @@
5
5
  = render_region :form_top, :locals => {:f => f}
6
6
 
7
7
  - render_region :form, :locals => {:f => f} do |form|
8
- - form.edit_name do
8
+ - form.name do
9
9
  %p
10
- = f.label :name, t('reader_extension.name')
11
- = f.text_field :name, :class => "textbox activate", :size => 32, :maxlength => 100
10
+ = f.label :forename
11
+ = f.text_field :forename, :class => "textbox activate", :size => 32, :maxlength => 100
12
+ %p
13
+ = f.label :surname
14
+ = f.text_field :surname, :class => "textbox activate", :size => 32, :maxlength => 100
12
15
 
13
16
  - form.edit_email do
14
17
  %p
15
- = f.label :email, t('reader_extension.email_address') , :class => "optional"
18
+ = f.label :email
16
19
  = f.text_field "email", :class => 'textbox', :size => 32, :maxlength => 255
17
20
 
18
- - form.edit_username do
21
+ - form.edit_nickname do
19
22
  %p
20
- = f.label :login, t('reader_extension.username') , :class => "optional"
23
+ = f.label :nickname
21
24
  = f.text_field "login", :class => 'textbox', :size => 32, :maxlength => 255
22
-
23
- - form.edit_readername do
24
- %p
25
- = f.label :login, t('reader_extension.readername')
26
- = f.text_field "login", :class => "textbox", :size => 32, :maxlength => 40
27
-
25
+
28
26
  - form.edit_password do
29
27
  = render "password_fields", :f => f
30
28
 
31
29
  - form.edit_description do
32
- %p
33
- = f.label :description, "Self-description", :class => "optional"
34
- ~ f.text_area "description", :size => "53x8", :class => "textarea"
30
+ - if Radiant.config['reader.show_descriptions?']
31
+ %p
32
+ = f.label :description, "Self-description", :class => "optional"
33
+ ~ f.text_area "description", :size => "53x8", :class => "textarea"
35
34
 
36
35
  - form.edit_notes do
37
36
  %p
@@ -1,4 +1,4 @@
1
- - @page_title = @reader.name + ' ' + t('reader_extension.account') + ' - ' + default_page_title
1
+ - @page_title = @reader.preferred_name + ' ' + t('reader_extension.account') + ' - ' + default_page_title
2
2
  - body_classes << 'edit_user'
3
3
 
4
4
  - render_region :main do |main|
@@ -17,8 +17,9 @@
17
17
  %th.reader_groups
18
18
  = t('reader_extension.groups')
19
19
  - thead.description_header do
20
- %th.reader_description
21
- = t('reader_extension.self_description')
20
+ - if Radiant.config['reader.show_descriptions?']
21
+ %th.reader_description
22
+ = t('reader_extension.self_description')
22
23
  - thead.modify_header do
23
24
  %th.modify
24
25
  = t('modify')
@@ -30,9 +31,9 @@
30
31
  - tbody.title_cell do
31
32
  %td{:class => reader.activated? ? 'name activated' : 'name inactive'}
32
33
  = link_to gravatar_for(reader, {:size => 32}, {:class => 'avatar avatar_32x32'}), edit_admin_reader_url(reader)
33
- = link_to reader.name, edit_admin_reader_url(reader), :class => reader.trusted? ? '' : 'untrusted'
34
+ = link_to reader.preferred_name, edit_admin_reader_url(reader), :class => reader.trusted? ? '' : 'untrusted'
34
35
  %span.info
35
- = "#{reader.login}"
36
+ = "#{reader.nickname}"
36
37
  - unless reader.notes.blank?
37
38
  %p.admin_notes
38
39
  %strong
@@ -48,8 +49,9 @@
48
49
  = reader.groups.collect{|g| link_to(g.name, admin_group_url(g)) }.join("\n")
49
50
 
50
51
  - tbody.description_cell do
51
- %td.reader_description
52
- = truncate_words(scrub_html(reader.description), 8)
52
+ - if Radiant.config['reader.show_descriptions?']
53
+ %td.reader_description
54
+ = truncate_words(scrub_html(reader.description), 8)
53
55
 
54
56
  - tbody.modify_cell do
55
57
  %td.actions
@@ -57,7 +59,7 @@
57
59
  - if reader.is_user?
58
60
  %span.action.disabled= image('minus_disabled') + ' ' + t('remove')
59
61
  - else
60
- = link_to(image('minus') + ' ' + t('remove'), admin_reader_url(reader), :method => :delete, :class => 'action', :confirm => t('reader_extension.really_delete_reader', :name => reader.name))
62
+ = link_to(image('minus') + ' ' + t('remove'), admin_reader_url(reader), :method => :delete, :class => 'action', :confirm => t('reader_extension.really_delete_reader', :name => reader.preferred_name))
61
63
 
62
64
 
63
65
  - render_region :bottom do |bottom|
@@ -9,7 +9,7 @@
9
9
  %tbody
10
10
  %tr.node.level-1
11
11
  %td.reader
12
- %span.title= @reader.name
12
+ %span.title= @reader.preferred_name
13
13
 
14
14
  - form_for [:admin, @reader], :html => { :method => :delete } do
15
15
  %p.buttons
@@ -1,5 +1,5 @@
1
1
  %p
2
2
  - if current_reader.newly_activated?
3
- = t("reader_extension.dashboard.welcome", :name => current_reader.name, :site => Radiant.config['site.title'])
3
+ = t("reader_extension.dashboard.welcome", :name => current_reader.preferred_name, :site => Radiant.config['site.title'])
4
4
  - else
5
- = t("reader_extension.dashboard.introduction", :name => current_reader.name, :site => Radiant.config['site.title'])
5
+ = t("reader_extension.dashboard.introduction", :name => current_reader.preferred_name, :site => Radiant.config['site.title'])
@@ -4,7 +4,7 @@
4
4
  %h3
5
5
  = link_to group.name, group_url(group)
6
6
 
7
- %p.context
7
+ %span.context
8
8
  = t("reader_extension.member_count", :count => group.readers.count) + '.'
9
9
 
10
10
  - if group.description
@@ -8,10 +8,10 @@
8
8
  = t("reader_extension.listing_denied")
9
9
  - else
10
10
  %td.gravatar
11
- = link_to gravatar_for(reader, {:size => 18}, {:class => 'gravatar'}), reader_url(reader), :title => reader.name
11
+ = link_to gravatar_for(reader, {:size => 18}, {:class => 'gravatar'}), reader_url(reader), :title => reader.preferred_name
12
12
  %td.name
13
13
  %h3
14
- = link_to reader.name, reader_url(reader)
14
+ = link_to reader.preferred_name, reader_url(reader)
15
15
  %td.role
16
16
  %p
17
17
  %span.role
@@ -54,7 +54,7 @@
54
54
  %p
55
55
  %strong
56
56
  = t('reader_extension.hello').titlecase
57
- = @reader.name + '!'
57
+ = @reader.preferred_name + '!'
58
58
  = t('reader_extension.new_password_instructions')
59
59
  - else
60
60
  %p.errornote
@@ -26,7 +26,7 @@
26
26
  - content_for :title do
27
27
  - if current_reader && current_reader.activated?
28
28
  = t('reader_extension.hello').titlecase
29
- = current_reader.name
29
+ = current_reader.preferred_name
30
30
  - else
31
31
  = t('reader_extension.activation_sent')
32
32
 
@@ -1,3 +1,3 @@
1
1
  - reader ||= @reader
2
- - unless reader.description.blank?
2
+ - if Radiant.config['reader.show_descriptions?'] && !reader.description.blank?
3
3
  = clean_html(reader.description)
@@ -4,6 +4,7 @@
4
4
  %h2
5
5
  = t('reader_extension.groups').titlecase
6
6
  = render :partial => 'groups/group', :collection => @groups
7
+
7
8
  - if @readers.any?
8
9
  %h2
9
10
  = t('reader_extension.people').titlecase
@@ -17,6 +18,11 @@
17
18
  - else
18
19
  = t('reader_extension.no_groups')
19
20
 
21
+ - if @readers.any?
22
+ %h2
23
+ = t('reader_extension.your_group_members')
24
+ = render :partial => 'readers/list', :locals => {:readers => @readers}
25
+
20
26
  - else
21
27
  = t('reader_extension.no_directory')
22
28
 
@@ -1,7 +1,7 @@
1
1
  .reader
2
2
  %h2
3
- = link_to gravatar_for(reader, :size => 128), reader_url(reader), :title => reader.name
4
- = link_to reader.name, reader_url(reader)
3
+ = link_to gravatar_for(reader, :size => 128), reader_url(reader), :title => reader.preferred_name
4
+ = link_to reader.preferred_name, reader_url(reader)
5
5
  %span.headernote
6
6
  = link_to '&nbsp;', reader_url(reader, :format => :vcard), :class => 'vcard'
7
7
 
@@ -8,7 +8,7 @@
8
8
  - else
9
9
  %div.contact
10
10
  %h3
11
- = link_to reader.name, reader_url(reader, :format => :vcard), :class => 'vcard', :title => t('reader_extension.directory.vcard_link')
11
+ = link_to reader.preferred_name, reader_url(reader, :format => :vcard), :class => 'vcard', :title => t('reader_extension.directory.vcard_link')
12
12
  %ul
13
13
  - if email = reader.email
14
14
  %li
@@ -4,10 +4,10 @@
4
4
  = t("reader_extension.listing_denied")
5
5
  - else
6
6
  %td.gravatar
7
- = link_to gravatar_for(reader, {:size => 18}, {:class => 'gravatar'}), reader_url(reader), :title => reader.name
7
+ = link_to gravatar_for(reader, {:size => 18}, {:class => 'gravatar'}), reader_url(reader), :title => reader.preferred_name
8
8
  %td.name
9
9
  %h3
10
- = link_to reader.name, reader_url(reader)
10
+ = link_to reader.preferred_name, reader_url(reader)
11
11
  %td.email
12
12
  %p
13
13
  = mail_to reader.email, nil, :encode => 'hex', :replace_at => " #{t('reader_extension.at')} "
@@ -3,12 +3,13 @@
3
3
  = t('reader_extension.separator')
4
4
 
5
5
  - content_for :title do
6
- = @reader.name
6
+ = @reader.preferred_name
7
7
 
8
8
  - content_for :introduction do
9
- = @reader.description
10
- %p
11
- = link_to t('reader_extension.edit_profile'), reader_edit_profile_url
9
+ - if Radiant.config['reader.show_descriptions?']
10
+ = @reader.description
11
+ %p
12
+ = link_to t('reader_extension.edit_profile'), reader_edit_profile_url
12
13
 
13
14
 
14
15
  - content_for :breadcrumbs do
@@ -10,6 +10,8 @@ Radiant.config do |config|
10
10
  reader.define 'profiles_path', :default => "directory"
11
11
  reader.define 'preferences_path', :default => "account"
12
12
  reader.define 'login_to', :default => "dashboard"
13
+ reader.define 'show_honorifics?', :default => false
14
+ reader.define 'show_descriptions?', :default => false
13
15
  end
14
16
  config.namespace('email') do |email|
15
17
  email.define 'layout', :select_from => lambda { Layout.all.map(&:name) }, :allow_blank => true
@@ -10,13 +10,14 @@ en:
10
10
  role: "Role"
11
11
  admin: "admin?"
12
12
  reader:
13
- description: "Explain yourself"
13
+ description: "A but of text about yourself"
14
14
  email: "Email address"
15
15
  forename: "Forename"
16
16
  honorific: "Title or rank"
17
17
  login: "Login username"
18
18
  mobile: "Mobile phone"
19
- name: "Your name"
19
+ name: "Full name"
20
+ nickname: "Nickname"
20
21
  password: "Password"
21
22
  password_confirmation: "Confirm password"
22
23
  phone: "Home phone"
@@ -49,6 +50,8 @@ en:
49
50
  name:
50
51
  blank: "please enter a name"
51
52
  too_long: "this is too long: 100 characters max"
53
+ nickname:
54
+ taken: "this name is already in use here"
52
55
  password:
53
56
  too_short: "this must have at least six characters"
54
57
  invalid: "this must include at least one non-letter"
@@ -60,7 +63,8 @@ en:
60
63
  layout: "Layout for forms"
61
64
  public?: "Readers list public"
62
65
  require_confirmation?: "Confirm email addresses"
63
- use_honorifics?: "Use honorifics"
66
+ show_honorifics?: "Show honorifics"
67
+ show_descriptions?: "Show biography"
64
68
  email:
65
69
  address: "Message reply-to"
66
70
  layout: "Email layout"
@@ -202,14 +206,17 @@ en:
202
206
  description: "This appears at the top of your profile page."
203
207
  email: "we will send activation instructions to this address"
204
208
  existing_password: "leave blank to keep present password. If changing, at least four characters."
209
+ forename: "This is normally how we refer to you..."
205
210
  honorific: "this is prepended to your name but only in a formal setting"
206
211
  login: "you can always use your email address instead"
207
212
  mobile: "without country code"
208
- name: "this is how you will be referred to on the site"
213
+ name: ""
214
+ nickname: "... but if you would rather we display a nickname, please enter it here. You can also log in with this name."
209
215
  new_password: "at least six characters, please, and with at least one non-letter character"
210
216
  phone: "with area code but no country code"
211
217
  post_country: "Please choose from the list"
212
218
  post_organisation: "You can omit this unless it's part of your postal address"
219
+ surname: ""
213
220
  unshareable: "To keep your contact information private and receive only administrative messages, check this box."
214
221
  form_problem: "there was a problem with the form"
215
222
  full_name: "full name"
@@ -413,6 +420,7 @@ en:
413
420
  your_description: "Your profile text"
414
421
  your_email: "Your email address"
415
422
  your_groups: "Your groups"
423
+ your_group_members: "All your group members"
416
424
  your_name: "Your name"
417
425
  readers: "Readers"
418
426
  settings: "Settings"
@@ -2,7 +2,6 @@ class ReaderHonorifics < ActiveRecord::Migration
2
2
 
3
3
  def self.up
4
4
  add_column :readers, :honorific, :string
5
- Radiant::Config['reader.use_honorifics?'] = false
6
5
  end
7
6
 
8
7
  def self.down
@@ -0,0 +1,13 @@
1
+ class SortOutNames < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :readers, :nickname, :string
4
+ Reader.all.each do |r|
5
+ r.send :combine_names
6
+ r.save if r.changed?
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ remove_column :readers, :nickname
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ class RemoveLogin < ActiveRecord::Migration
2
+ def self.up
3
+ Reader.reset_column_information
4
+ Reader.all.each do |r|
5
+ r.nickname ||= r.login
6
+ r.save if r.changed?
7
+ end
8
+ remove_column :readers, :login
9
+ end
10
+
11
+ def self.down
12
+ add_column :readers, :login, :string
13
+ end
14
+ end
@@ -1,5 +1,5 @@
1
1
  module RadiantReaderExtension
2
- VERSION = '3.0.20'
2
+ VERSION = '3.0.23'
3
3
  SUMMARY = %q{Reader/viewer/visitor registration, login and access-control for Radiant CMS}
4
4
  DESCRIPTION = %q{Provides reader/member/user registration and management functions including password-reminder, group-based page access control and administrative email.}
5
5
  URL = "http://radiant.spanner.org/reader"
@@ -29,7 +29,7 @@ module ReaderAdminUI
29
29
  OpenStruct.new.tap do |reader|
30
30
  reader.edit = Radiant::AdminUI::RegionSet.new do |edit|
31
31
  edit.main.concat %w{edit_header edit_form}
32
- edit.form.concat %w{edit_name edit_email edit_username edit_password reader_groups edit_description edit_notes}
32
+ edit.form.concat %w{edit_name edit_email edit_nickname edit_password reader_groups edit_description edit_notes}
33
33
  edit.form_bottom.concat %w{edit_timestamp edit_buttons}
34
34
  end
35
35
  reader.index = Radiant::AdminUI::RegionSet.new do |index|
@@ -76,7 +76,7 @@ module ReaderTags
76
76
  tag.expand if get_reader(tag)
77
77
  end
78
78
 
79
- [:name, :forename, :email, :description, :login].each do |field|
79
+ [:name, :forename, :surname, :nickname, :preferred_name, :email, :description, :login].each do |field|
80
80
  desc %{
81
81
  Displays the #{field} field of the current reader.
82
82
  <pre><code><r:reader:#{field} /></code></pre>
@@ -111,7 +111,7 @@ module ReaderTags
111
111
  %{<div class="remote_controls"></div>}
112
112
  else
113
113
  if tag.locals.reader = Reader.current
114
- welcome = %{<span class="greeting">#{I18n.t('reader_extension.navigation.greeting', :name => tag.locals.reader.name)}</span>. }
114
+ welcome = %{<span class="greeting">#{I18n.t('reader_extension.navigation.greeting', :name => tag.locals.reader.preferred_name)}</span>. }
115
115
  if tag.locals.reader.activated?
116
116
  welcome << %{
117
117
  #{I18n.t('reader_extension.not_you')} <a href="#{reader_logout_path}">#{I18n.t('reader_extension.navigation.log_out')}</a>.
@@ -27,7 +27,6 @@ module ReaderUser
27
27
  def update_with(att)
28
28
  self.skip_reader_update = true
29
29
  self.confirm_password = false
30
- p "updating user attributes with #{att.inspect}"
31
30
  self.update_attributes(att)
32
31
  self.skip_reader_update = false
33
32
  end
@@ -75,6 +75,14 @@ form.friendly
75
75
  margin: 0 0 2em 0
76
76
  p
77
77
  margin: 1em 0 0 0
78
+ overflow: hidden
79
+ span.semi
80
+ display: block
81
+ float: left
82
+ width: 48%
83
+ margin-right: 1%
84
+ &.clear
85
+ clear: both
78
86
  input.login
79
87
  width: 95%
80
88
  font-size: 140%
@@ -180,7 +180,7 @@ describe AccountsController do
180
180
  describe "that does not validate" do
181
181
  before do
182
182
  login_as_reader(:normal)
183
- put :update, {:id => reader_id(:normal), :reader => {:login => readers(:visible).login}}
183
+ put :update, {:id => reader_id(:normal), :reader => {:nickname => readers(:visible).nickname}}
184
184
  end
185
185
 
186
186
  it "should re-render the edit form" do
@@ -71,7 +71,7 @@ From <r:sender:name />
71
71
  create_model :reader, name.symbolize, {
72
72
  :name => name,
73
73
  :email => "#{name}@spanner.org",
74
- :login => name.downcase,
74
+ :nickname => name,
75
75
  :activated_at => Time.now - 1.week,
76
76
  :password_salt => "golly",
77
77
  :password => 'passw0rd',
@@ -108,9 +108,6 @@ From <r:sender:name />
108
108
  }.merge(attributes)
109
109
  end
110
110
 
111
-
112
-
113
-
114
111
  def login_as_reader(reader)
115
112
  activate_authlogic
116
113
  login_reader = reader.is_a?(Reader) ? reader : readers(reader)
@@ -22,7 +22,7 @@ describe "Reader Tags" do
22
22
  it { should render(%{<r:reader:name />}).as(person.name) }
23
23
  it { should render(%{<r:if_reader>hello</r:if_reader>}).as('hello') }
24
24
  it { should render(%{<r:unless_reader>hello</r:unless_reader>}).as('') }
25
- [:name, :forename, :email, :description, :login].each { |field| it { should render(%{<r:reader:#{field} id="#{person.id}" />}).as(person.send(field)) } }
25
+ [:name, :nickname, :forename, :surname, :preferred_name, :email, :description].each { |field| it { should render(%{<r:reader:#{field} id="#{person.id}" />}).as(person.send(field)) } }
26
26
  end
27
27
 
28
28
  describe "on an uncached page" do
@@ -41,13 +41,13 @@ describe "Reader Tags" do
41
41
  it { should render(%{<r:reader:name />}).as('') }
42
42
  it { should render(%{<r:reader:welcome />}).as('') }
43
43
  it { should render(%{<r:reader_welcome />}).as(%{<div class="remote_controls"></div>}) }
44
- [:name, :forename, :email, :description, :login].each { |field| it { should render(%{<r:reader id="#{another.id}"><r:#{field} /></r:reader>}).as(another.send(field)) } }
44
+ [:name, :nickname, :forename, :surname, :preferred_name, :email, :description].each { |field| it { should render(%{<r:reader id="#{another.id}"><r:#{field} /></r:reader>}).as(another.send(field)) } }
45
45
  end
46
46
  end
47
47
 
48
48
  describe "utility tags" do
49
49
  subject { page }
50
- it { should render(%{<r:truncated chars="50">All happy families are alike; each unhappy family is unhappy in its own way.</r:truncated>}).as(' All happy families are alike; each unhapp&hellip;') }
50
+ it { should render(%{<r:truncated chars="50">All happy families are alike; each unhappy family is unhappy in its own way.</r:truncated>}).as('All happy families are alike; each unhappy&hellip;') }
51
51
  it { should render(%{<r:truncated words="5" omission="">All happy families are alike; each unhappy family is unhappy in its own way.</r:truncated>}).as('All happy families are alike;') }
52
52
  it { should render(%{<r:truncated words="5" allow_html="true" omission=" (tbc)">All <em>happy families</em> are alike; each unhappy family is unhappy in its own way.</r:truncated>}).as('All <em>happy families</em> are alike; (tbc)') }
53
53
  end
@@ -15,14 +15,20 @@ describe Reader do
15
15
 
16
16
  describe "on validation" do
17
17
  before do
18
- @reader = Reader.new :name => "Test Reader", :email => 'test@spanner.org', :login => 'test', :password => 'passw0rd', :password_confirmation => 'passw0rd'
18
+ @reader = Reader.new :name => "Test Reader", :email => 'test@spanner.org', :nickname => 'test', :password => 'passw0rd', :password_confirmation => 'passw0rd'
19
19
  @reader.should be_valid
20
20
  end
21
21
 
22
- it "should require a name" do
22
+ it "should require (but derive) a name" do
23
23
  @reader.name = nil
24
+ @reader.should be_valid
25
+ @reader.forename = @reader.surname = @reader.name = nil
24
26
  @reader.should_not be_valid
25
27
  @reader.errors.on(:name).should_not be_empty
28
+ @reader.forename = "very"
29
+ @reader.surname = "testy"
30
+ @reader.should be_valid
31
+ @reader.name.should == "very testy"
26
32
  end
27
33
 
28
34
  it "should require a valid email address" do
@@ -42,16 +48,16 @@ describe Reader do
42
48
  @reader.should_not be_valid
43
49
  end
44
50
 
45
- it "should require a unique login" do
46
- @reader.login = @existing_reader.login
51
+ it "should require a unique nickname" do
52
+ @reader.nickname = @existing_reader.nickname
47
53
  @reader.should_not be_valid
48
- @reader.errors.on(:login).should_not be_empty
54
+ @reader.errors.on(:nickname).should_not be_empty
49
55
  end
50
56
  end
51
57
 
52
58
  describe "on creation" do
53
59
  before do
54
- @reader = Reader.create :name => "Test Reader", :email => 'test@spanner.org', :login => 'test', :password => 'passw0rd', :password_confirmation => 'passw0rd'
60
+ @reader = Reader.create :name => "Test Reader", :email => 'test@spanner.org', :nickname => 'test', :password => 'passw0rd', :password_confirmation => 'passw0rd'
55
61
  end
56
62
 
57
63
  it 'should await activation' do
@@ -75,11 +81,11 @@ describe Reader do
75
81
  it "should create a matching reader if necessary" do
76
82
  user = users(:admin)
77
83
  reader = Reader.for_user(user)
78
- [:name, :email, :login, :created_at, :notes].each do |att|
84
+ [:name, :email, :created_at, :notes].each do |att|
79
85
  reader.send(att).should == user.send(att)
80
86
  end
81
87
  reader.crypted_password.should == user.password
82
- ReaderSession.new(:login => 'admin', :password => 'password').should be_valid
88
+ ReaderSession.new(:email => user.email, :password => 'password').should be_valid
83
89
  reader.is_user?.should be_true
84
90
  reader.is_admin?.should be_true
85
91
  end
@@ -116,7 +122,7 @@ describe Reader do
116
122
 
117
123
  describe "on activation" do
118
124
  before do
119
- @reader = Reader.create :name => "Test Reader", :email => 'test@spanner.org', :login => 'another_login', :password => 'passw0rd', :password_confirmation => 'passw0rd', :trusted => 1
125
+ @reader = Reader.create :name => "Test Reader", :email => 'test@spanner.org', :nickname => 'another_nickname', :password => 'passw0rd', :password_confirmation => 'passw0rd', :trusted => 1
120
126
  end
121
127
 
122
128
  it 'should be retrieved by id and activation code' do
@@ -137,20 +143,20 @@ describe Reader do
137
143
 
138
144
  describe "on login" do
139
145
  before do
140
- @reader = Reader.create :name => "Test Reader", :email => 'test@spanner.org', :login => 'test', :password => 'h00haa', :password_confirmation => 'h00haa'
146
+ @reader = Reader.create :name => "Test Reader", :email => 'test@spanner.org', :nickname => 'test', :password => 'h00haa', :password_confirmation => 'h00haa'
141
147
  @reader.activate!
142
148
  end
143
149
 
144
150
  it 'should authenticate' do
145
- ReaderSession.new(:login => 'test', :password => 'h00haa').should be_valid
151
+ ReaderSession.new(:email => 'test@spanner.org', :password => 'h00haa').should be_valid
146
152
  end
147
153
 
148
154
  it 'should not authenticate with bad password' do
149
- ReaderSession.new(:login => 'test', :password => 'corcovado').should_not be_valid
155
+ ReaderSession.new(:email => 'test@spanner.org', :password => 'corcovado').should_not be_valid
150
156
  end
151
157
 
152
158
  it 'should not authenticate if it does not exist' do
153
- ReaderSession.new(:login => 'loch ness monster', :password => 'blotto').should_not be_valid
159
+ ReaderSession.new(:email => 'loch ness monster', :password => 'blotto').should_not be_valid
154
160
  end
155
161
  end
156
162
  end
@@ -1,4 +1,4 @@
1
1
  --colour
2
2
  --format specdoc
3
3
  --loadby mtime
4
- --reverse
4
+ --reverse
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radiant-reader-extension
3
3
  version: !ruby/object:Gem::Version
4
- hash: 47
4
+ hash: 41
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 20
10
- version: 3.0.20
9
+ - 23
10
+ version: 3.0.23
11
11
  platform: ruby
12
12
  authors:
13
13
  - William Ross
@@ -182,6 +182,7 @@ files:
182
182
  - app/models/reader_session.rb
183
183
  - app/views/accounts/_choose_memberships.html.haml
184
184
  - app/views/accounts/_controls.html.haml
185
+ - app/views/accounts/_edit_names.html.haml
185
186
  - app/views/accounts/_extra_controls.html.haml
186
187
  - app/views/accounts/_flasher.html.haml
187
188
  - app/views/accounts/_form.html.haml
@@ -301,6 +302,8 @@ files:
301
302
  - db/migrate/20110814070858_message_has_many_groups.rb
302
303
  - db/migrate/20110905194602_group_ancestry.rb
303
304
  - db/migrate/20110908194602_membership_attributes.rb
305
+ - db/migrate/20111013134949_sort_out_names.rb
306
+ - db/migrate/20111013203306_remove_login.rb
304
307
  - lib/controller_extensions.rb
305
308
  - lib/group_tags.rb
306
309
  - lib/grouped_model.rb
@@ -328,6 +331,7 @@ files:
328
331
  - public/stylesheets/sass/admin/reader.sass
329
332
  - public/stylesheets/sass/admin/reader_group.sass
330
333
  - public/stylesheets/sass/reader.sass
334
+ - radiant-reader-extension-3.1.0.gem
331
335
  - radiant-reader-extension.gemspec
332
336
  - Rakefile
333
337
  - reader_extension.rb
@@ -356,7 +360,7 @@ files:
356
360
  homepage: http://radiant.spanner.org/reader
357
361
  licenses: []
358
362
 
359
- post_install_message: "\n Add this to your radiant project with a line in your Gemfile:\n\n gem 'radiant-reader-extension', '~> 3.0.20'\n\n and if you haven't already, remember to enable ActionMailer in your\n project's config/environment.rb.\n "
363
+ post_install_message: "\n Add this to your radiant project with a line in your Gemfile:\n\n gem 'radiant-reader-extension', '~> 3.0.23'\n\n and if you haven't already, remember to enable ActionMailer in your\n project's config/environment.rb.\n "
360
364
  rdoc_options: []
361
365
 
362
366
  require_paths: