hello-rails 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -4
  3. data/app/controllers/hello/concerns/management/forgot_password.rb +1 -1
  4. data/app/controllers/hello/concerns/registration/sign_up.rb +7 -3
  5. data/app/controllers/hello/registration/sign_up_controller.rb +9 -1
  6. data/app/models/access.rb +2 -1
  7. data/app/models/credential.rb +2 -1
  8. data/app/models/email_credential.rb +2 -1
  9. data/app/models/password_credential.rb +2 -1
  10. data/app/models/user.rb +2 -1
  11. data/app/views/hello/shared/_nav_pills.html.erb +0 -2
  12. data/config/locales/hello.fr.yml +2 -4
  13. data/db/migrate/3_create_users.rb +10 -15
  14. data/lib/data/locales.yml +228 -0
  15. data/lib/generators/hello/install/install_generator.rb +8 -29
  16. data/lib/generators/hello/install/templates/initializer.rb +1 -1
  17. data/lib/generators/hello/install/templates/models/concerns/user/authorization.rb +8 -13
  18. data/lib/generators/hello/install/templates/models/user.rb +2 -1
  19. data/lib/generators/hello/users/USAGE +10 -0
  20. data/lib/generators/hello/{install/templates/users → users/templates/app}/controllers/users_controller.rb +2 -4
  21. data/lib/generators/hello/{install/templates/users → users/templates/app}/views/users/index.html.erb +1 -1
  22. data/lib/generators/hello/{install/templates/users → users/templates/app}/views/users/list.html.erb +3 -1
  23. data/lib/generators/hello/{install/templates/users → users/templates/app}/views/users/new.html.erb +2 -2
  24. data/lib/generators/hello/{install/templates/users → users/templates/app}/views/users/show.html.erb +0 -0
  25. data/lib/generators/hello/users/users_generator.rb +21 -0
  26. data/lib/hello/business/registration/sign_up.rb +30 -122
  27. data/lib/hello/locales.rb +1 -232
  28. data/lib/hello/rails_active_record/access.rb +12 -10
  29. data/lib/hello/rails_active_record/credential.rb +22 -18
  30. data/lib/hello/rails_active_record/email_credential.rb +12 -20
  31. data/lib/hello/rails_active_record/password_credential.rb +11 -32
  32. data/lib/hello/rails_active_record/user.rb +75 -54
  33. data/lib/hello/rails_controller.rb +1 -3
  34. data/lib/hello/rails_controller/restrict_by_role.rb +2 -2
  35. data/lib/hello/version.rb +1 -1
  36. data/spec/bdd/hello/authentication/classic_sign_in_spec.rb +2 -2
  37. data/spec/bdd/hello/internalionalization/anyone_can_change_their_locale/change_locale_on_the_sign_in_form_spec.rb +1 -1
  38. data/spec/bdd/hello/management/manage_email_credentials/manage_email_credentials_emails_page_spec.rb +7 -7
  39. data/spec/bdd/hello/management/manage_password_credentials/manage_password_forgot_password_spec.rb +1 -1
  40. data/spec/bdd/hello/management/manage_password_credentials/manage_password_reset_password_spec.rb +1 -1
  41. data/spec/bdd/hello/management/manage_profile/manage_profile_page_spec.rb +0 -2
  42. data/spec/bdd/hello/other/create_user_spec.rb +1 -3
  43. data/spec/bdd/hello/other/impersonate_user_spec.rb +1 -2
  44. data/spec/bdd/hello/other/list_users_spec.rb +2 -4
  45. data/spec/bdd/hello/registration/classic_sign_up_spec.rb +3 -4
  46. data/spec/bdd/hello/support.rb +0 -4
  47. data/spec/business/hello/registration/sign_up_spec.rb +10 -2
  48. data/spec/controllers/authentication_spec.rb +3 -3
  49. data/spec/models/create_and_destroy/email_credential_create_and_destroy_spec.rb +81 -0
  50. data/spec/models/create_and_destroy/password_credential_create_and_destroy_spec.rb +60 -0
  51. data/spec/models/create_and_destroy/user_create_and_destroy_spec.rb +124 -0
  52. data/spec/models/credential_spec.rb +12 -3
  53. data/spec/models/email_credential_spec.rb +1 -2
  54. data/spec/models/password_credential_spec.rb +1 -2
  55. data/spec/models/user_spec.rb +87 -27
  56. data/spec/requests/forgot_password_spec.rb +1 -1
  57. data/spec/support/factories.rb +10 -14
  58. data/spec/support/helpers/given.rb +8 -16
  59. data/spec/support/helpers/when.rb +0 -1
  60. metadata +42 -38
  61. data/lib/generators/hello/from_devise/USAGE +0 -8
  62. data/lib/generators/hello/from_devise/from_devise_generator.rb +0 -13
  63. data/lib/generators/hello/from_devise/templates/from_devise.migration.rb +0 -39
  64. data/spec/models/hello/sign_up_model_spec.rb +0 -64
@@ -14,7 +14,7 @@ Hello.configure do |config|
14
14
  config.password_length = 4..250
15
15
 
16
16
  config.sign_up_disabled = false # {reason: "standard maintenance", until: "3PM"}
17
- config.sign_up_fields = %w(username time_zone locale name)
17
+ config.sign_up_fields = %w(username email password time_zone locale name)
18
18
 
19
19
  config.locales = %w(en es fr pl pt-BR zh-CN)
20
20
  config.time_zones = Hello::TimeZones.all
@@ -1,21 +1,16 @@
1
- class User < Hello::RailsActiveRecord::User
2
- module Authorization
1
+ module User::Authorization
3
2
 
4
- def guest?
3
+ def role_is?(string)
4
+ case string.to_s
5
+ when 'guest'
5
6
  %w(guest).include?(role)
6
- end
7
-
8
- def onboarding?
7
+ when 'onboarding'
9
8
  %w(onboarding).include?(role)
10
- end
11
-
12
- def user?
9
+ when 'user'
13
10
  %w(user webmaster).include?(role)
14
- end
15
-
16
- def webmaster?
11
+ when 'webmaster'
17
12
  %w(webmaster).include?(role)
18
13
  end
19
-
20
14
  end
15
+
21
16
  end
@@ -1,4 +1,5 @@
1
- class User < Hello::RailsActiveRecord::User
1
+ class User < ApplicationRecord
2
+ include Hello::RailsActiveRecord::User
2
3
  include Authorization
3
4
 
4
5
  def to_param
@@ -0,0 +1,10 @@
1
+ Description:
2
+ Suggested scaffold for users
3
+
4
+ Example:
5
+ rails generate hello:users
6
+
7
+ This will create:
8
+ app/controller/users_controller.rb
9
+ app/views/users/[...]
10
+
@@ -36,16 +36,14 @@ class UsersController < ApplicationController
36
36
 
37
37
  # GET /users/new
38
38
  def new
39
- @starting_role = 'onboarding'
40
39
  end
41
40
 
42
41
  # POST /users
43
42
  def create
44
- if @user.register(params.require(:user))
45
- @user.user.update!(role: params[:role])
43
+ create_user_params = params.require(:user).permit!
44
+ if @user.register(create_user_params)
46
45
  redirect_to new_user_path, notice: t('hello.business.registration.sign_up.success')
47
46
  else
48
- @starting_role = params[:role]
49
47
  render action: :new
50
48
  end
51
49
  end
@@ -1,6 +1,6 @@
1
1
  <h1>Listing Users (<%= @count %>)</h1>
2
2
 
3
- <% if current_user && current_user.webmaster? %>
3
+ <% if current_user && current_user.role_is?(:webmaster) %>
4
4
  <p><%= link_to "View User List as a Webmaster", list_users_path %></p>
5
5
  <% end %>
6
6
 
@@ -1,5 +1,7 @@
1
1
  <h1>Listing Users (<%= @count %>)</h1>
2
2
 
3
+ <%= link_to('New User as a Webmaster', new_user_path) %>
4
+
3
5
  <table class="table table-condensed">
4
6
  <thead>
5
7
  <tr>
@@ -11,7 +13,7 @@
11
13
  <th>Time zone</th>
12
14
  <th>Credentials</th>
13
15
  <th>Accesses</th>
14
- <!-- actions -->
16
+ <!-- actions -->
15
17
  <th colspan="1"></th>
16
18
  </tr>
17
19
  </thead>
@@ -6,9 +6,9 @@
6
6
  <% end %>
7
7
 
8
8
  <div class="form-group">
9
- <%= label_tag :role, nil, class: "col-sm-4 control-label" %>
9
+ <%= f.label :role, class: "col-sm-4 control-label" %>
10
10
  <div class="col-sm-4">
11
- <%= text_field_tag :role, @starting_role, class: "form-control", placeholder: "Role" %>
11
+ <%= f.text_field :role, class: "form-control", placeholder: "Role" %>
12
12
  </div>
13
13
  </div>
14
14
 
@@ -0,0 +1,21 @@
1
+ class Hello::UsersGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ def copy_the_files
5
+ directory 'app'
6
+ end
7
+
8
+ def append_the_routes
9
+ route %(
10
+ resources :users, only: [:index, :show, :new, :create] do
11
+ collection do
12
+ get 'list'
13
+ end
14
+ member do
15
+ post 'impersonate'
16
+ end
17
+ end
18
+ )
19
+ end
20
+
21
+ end
@@ -2,16 +2,21 @@ module Hello
2
2
  module Business
3
3
  module Registration
4
4
  class SignUp < Base
5
- attr_reader :email_credential, :password_credential, :user
5
+ attr_reader :user
6
6
 
7
7
  def initialize
8
- generate_accessors
9
- write_defaults
8
+ init_user
10
9
  end
11
10
 
12
11
  def register(attrs)
13
- write_attrs(attrs.with_indifferent_access)
14
- create_models
12
+ init_user(attrs)
13
+
14
+ user.save.tap do
15
+ merge_errors_for(@email_credential)
16
+ merge_errors_for(@password_credential)
17
+ errors.delete(:email_credentials)
18
+ errors.delete(:password_credentials)
19
+ end
15
20
  end
16
21
 
17
22
  # errors.added? DOES NOT WORK when the validation was given a custom message :)
@@ -21,138 +26,41 @@ module Hello
21
26
 
22
27
  # errors.added? DOES NOT WORK when the validation was given a custom message :)
23
28
  def username_taken?
24
- @user && user.errors.added?(:username, :taken)
25
- end
26
-
27
- private
28
-
29
- # initialize helpers
30
-
31
- def generate_accessors
32
- self.class.send :attr_accessor, *all_fields
33
- end
34
-
35
- def all_fields
36
- user_fields + %w(email password)
37
- end
38
-
39
- def write_defaults
40
- # defaults.each { |k, v| instance_variable_set(:"@#{k}", v) }
41
- defaults.each { |k, v| send("#{k}=", v) }
42
- end
43
-
44
- # save helpers
45
-
46
- def write_attrs(attrs)
47
- # attrs.slice(*all_fields).each { |k, v| instance_variable_set(:"@#{k}", v) if v }
48
- attrs.slice(*all_fields).each { |k, v| send("#{k}=", v) if v }
49
- end
50
-
51
- # NOTE:
52
- # All validations are delegated to the models
53
- def create_models
54
- validate_presences
55
- return false if errors.any?
56
-
57
- build_and_validate_models
58
- return false if errors.any?
59
-
60
- save_models!
61
- true
62
- end
63
-
64
- def validate_presences
65
- validates_presence_of :email if validates_presence_of_email?
66
-
67
- validates_presence_of :username if validates_presence_of_username?
68
-
69
- validates_presence_of :password if validates_presence_of_password?
70
-
71
- ::User.validators.each do |validator|
72
- next unless validator.is_a?(ActiveRecord::Validations::PresenceValidator)
73
- next unless validator.attributes.first.to_sym != :username
74
- options = validator.options.dup
75
- options[:attributes] = validator.attributes
76
- validates_with(validator.class, options)
77
- end
29
+ errors.added?(:username, :taken)
78
30
  end
79
31
 
80
- def build_and_validate_models
81
- # user & username
82
- @user = ::User.new(user_attributes)
83
- if username.blank? && !validates_presence_of_username?
84
- user.set_generated_username
85
- end
86
- merge_errors_for(user)
87
-
88
- # email_credential & email
89
- if email.present? || validates_presence_of_email?
90
- @email_credential = ::EmailCredential.new user: @user, email: email
91
- merge_errors_for(email_credential)
92
- end
93
-
94
- # password_credential & password
95
- @password_credential = ::PasswordCredential.new user: @user, password: password
96
- if password.blank? && !validates_presence_of_password?
97
- password_credential.set_generated_password
98
- end
99
- merge_errors_for(password_credential)
100
- end
101
-
102
- def merge_errors_for(model)
103
- model.valid?
104
- model.errors.each do |k, v|
105
- errors.add(k, v)
106
- end
107
- end
108
-
109
- def save_models!
110
- user.save!
111
- email_credential && email_credential.save!
112
- password_credential.save!
113
- end
114
-
115
- # returns {name: "...", city: "..."}
116
- def user_attributes
117
- r = {}
118
- user_fields.each { |k| r[k.to_s] = instance_variable_get(:"@#{k}") }
119
- r['role'] = starting_role
120
- r
32
+ def method_missing(method_name, *args, &block)
33
+ user.send(method_name)
121
34
  end
122
35
 
123
- def starting_role
124
- 'onboarding'
125
- end
36
+ private
126
37
 
127
- def user_fields
128
- Hello.configuration.sign_up_fields.map(&:to_s)
38
+ def init_user(attrs={})
39
+ attrs.reverse_merge!(defaults)
40
+ @user = User.new(attrs)
41
+ @email_credential = user.email_credentials.first
42
+ @password_credential = user.password_credentials.first
43
+ @errors = user.errors
129
44
  end
130
45
 
131
46
  def defaults
132
47
  {
133
48
  locale: I18n.locale.to_s,
134
- time_zone: Time.zone.name
49
+ time_zone: Time.zone.name,
50
+ email: '',
51
+ password: '',
135
52
  }
136
53
  end
137
54
 
138
- # config helpers
139
-
140
- def validates_presence_of_email?
141
- Hello.configuration.email_presence
142
- end
143
-
144
- def validates_presence_of_username?
145
- Hello.configuration.username_presence
146
- end
147
-
148
- def validates_presence_of_password?
149
- Hello.configuration.password_presence
55
+ def merge_errors_for(model)
56
+ if model
57
+ model.valid?
58
+ model.errors.each do |k, v|
59
+ errors.add(k, v)
60
+ end
61
+ end
150
62
  end
151
63
 
152
- # just because!
153
-
154
- def self._reflect_on_association(*_args)
155
- end
156
64
  end
157
65
  end
158
66
  end
@@ -1,238 +1,7 @@
1
1
  module Hello
2
2
  module Locales
3
- ALL = {
4
- 'af' => 'Afrikaans',
5
- 'af-ZA' => 'Afrikaans (South Africa)',
6
- 'ar' => 'Arabic',
7
- 'ar-AE' => 'Arabic (U.A.E.)',
8
- 'ar-BH' => 'Arabic (Bahrain)',
9
- 'ar-DZ' => 'Arabic (Algeria)',
10
- 'ar-EG' => 'Arabic (Egypt)',
11
- 'ar-IQ' => 'Arabic (Iraq)',
12
- 'ar-JO' => 'Arabic (Jordan)',
13
- 'ar-KW' => 'Arabic (Kuwait)',
14
- 'ar-LB' => 'Arabic (Lebanon)',
15
- 'ar-LY' => 'Arabic (Libya)',
16
- 'ar-MA' => 'Arabic (Morocco)',
17
- 'ar-OM' => 'Arabic (Oman)',
18
- 'ar-QA' => 'Arabic (Qatar)',
19
- 'ar-SA' => 'Arabic (Saudi Arabia)',
20
- 'ar-SY' => 'Arabic (Syria)',
21
- 'ar-TN' => 'Arabic (Tunisia)',
22
- 'ar-YE' => 'Arabic (Yemen)',
23
- 'az' => 'Azeri (Latin)',
24
- 'az-AZ' => 'Azeri (Cyrillic) (Azerbaijan)',
25
- 'be' => 'Belarusian',
26
- 'be-BY' => 'Belarusian (Belarus)',
27
- 'bg' => 'Bulgarian',
28
- 'bg-BG' => 'Bulgarian (Bulgaria)',
29
- 'bs-BA' => 'Bosnian (Bosnia and Herzegovina)',
30
- 'ca' => 'Catalan',
31
- 'ca-ES' => 'Catalan (Spain)',
32
- 'cs' => 'Czech',
33
- 'cs-CZ' => 'Czech (Czech Republic)',
34
- 'cy' => 'Welsh',
35
- 'cy-GB' => 'Welsh (United Kingdom)',
36
- 'da' => 'Danish',
37
- 'da-DK' => 'Danish (Denmark)',
38
- 'de' => 'German',
39
- 'de-AT' => 'German (Austria)',
40
- 'de-CH' => 'German (Switzerland)',
41
- 'de-DE' => 'German (Germany)',
42
- 'de-LI' => 'German (Liechtenstein)',
43
- 'de-LU' => 'German (Luxembourg)',
44
- 'dv' => 'Divehi',
45
- 'dv-MV' => 'Divehi (Maldives)',
46
- 'el' => 'Greek',
47
- 'el-GR' => 'Greek (Greece)',
48
- 'en' => 'English',
49
- 'en-AU' => 'English (Australia)',
50
- 'en-BZ' => 'English (Belize)',
51
- 'en-CA' => 'English (Canada)',
52
- 'en-CB' => 'English (Caribbean)',
53
- 'en-GB' => 'English (United Kingdom)',
54
- 'en-IE' => 'English (Ireland)',
55
- 'en-JM' => 'English (Jamaica)',
56
- 'en-NZ' => 'English (New Zealand)',
57
- 'en-PH' => 'English (Republic of the Philippines)',
58
- 'en-TT' => 'English (Trinidad and Tobago)',
59
- 'en-US' => 'English (United States)',
60
- 'en-ZA' => 'English (South Africa)',
61
- 'en-ZW' => 'English (Zimbabwe)',
62
- 'eo' => 'Esperanto',
63
- 'es' => 'Spanish',
64
- 'es-AR' => 'Spanish (Argentina)',
65
- 'es-BO' => 'Spanish (Bolivia)',
66
- 'es-CL' => 'Spanish (Chile)',
67
- 'es-CO' => 'Spanish (Colombia)',
68
- 'es-CR' => 'Spanish (Costa Rica)',
69
- 'es-DO' => 'Spanish (Dominican Republic)',
70
- 'es-EC' => 'Spanish (Ecuador)',
71
- 'es-ES' => 'Spanish (Spain)',
72
- 'es-GT' => 'Spanish (Guatemala)',
73
- 'es-HN' => 'Spanish (Honduras)',
74
- 'es-MX' => 'Spanish (Mexico)',
75
- 'es-NI' => 'Spanish (Nicaragua)',
76
- 'es-PA' => 'Spanish (Panama)',
77
- 'es-PE' => 'Spanish (Peru)',
78
- 'es-PR' => 'Spanish (Puerto Rico)',
79
- 'es-PY' => 'Spanish (Paraguay)',
80
- 'es-SV' => 'Spanish (El Salvador)',
81
- 'es-UY' => 'Spanish (Uruguay)',
82
- 'es-VE' => 'Spanish (Venezuela)',
83
- 'et' => 'Estonian',
84
- 'et-EE' => 'Estonian (Estonia)',
85
- 'eu' => 'Basque',
86
- 'eu-ES' => 'Basque (Spain)',
87
- 'fa' => 'Farsi',
88
- 'fa-IR' => 'Farsi (Iran)',
89
- 'fi' => 'Finnish',
90
- 'fi-FI' => 'Finnish (Finland)',
91
- 'fo' => 'Faroese',
92
- 'fo-FO' => 'Faroese (Faroe Islands)',
93
- 'fr' => 'French',
94
- 'fr-BE' => 'French (Belgium)',
95
- 'fr-CA' => 'French (Canada)',
96
- 'fr-CH' => 'French (Switzerland)',
97
- 'fr-FR' => 'French (France)',
98
- 'fr-LU' => 'French (Luxembourg)',
99
- 'fr-MC' => 'French (Principality of Monaco)',
100
- 'gl' => 'Galician',
101
- 'gl-ES' => 'Galician (Spain)',
102
- 'gu' => 'Gujarati',
103
- 'gu-IN' => 'Gujarati (India)',
104
- 'he' => 'Hebrew',
105
- 'he-IL' => 'Hebrew (Israel)',
106
- 'hi' => 'Hindi',
107
- 'hi-IN' => 'Hindi (India)',
108
- 'hr' => 'Croatian',
109
- 'hr-BA' => 'Croatian (Bosnia and Herzegovina)',
110
- 'hr-HR' => 'Croatian (Croatia)',
111
- 'hu' => 'Hungarian',
112
- 'hu-HU' => 'Hungarian (Hungary)',
113
- 'hy' => 'Armenian',
114
- 'hy-AM' => 'Armenian (Armenia)',
115
- 'id' => 'Indonesian',
116
- 'id-ID' => 'Indonesian (Indonesia)',
117
- 'is' => 'Icelandic',
118
- 'is-IS' => 'Icelandic (Iceland)',
119
- 'it' => 'Italian',
120
- 'it-CH' => 'Italian (Switzerland)',
121
- 'it-IT' => 'Italian (Italy)',
122
- 'ja' => 'Japanese',
123
- 'ja-JP' => 'Japanese (Japan)',
124
- 'ka' => 'Georgian',
125
- 'ka-GE' => 'Georgian (Georgia)',
126
- 'kk' => 'Kazakh',
127
- 'kk-KZ' => 'Kazakh (Kazakhstan)',
128
- 'kn' => 'Kannada',
129
- 'kn-IN' => 'Kannada (India)',
130
- 'ko' => 'Korean',
131
- 'ko-KR' => 'Korean (Korea)',
132
- 'kok' => 'Konkani',
133
- 'kok-IN' => 'Konkani (India)',
134
- 'ky' => 'Kyrgyz',
135
- 'ky-KG' => 'Kyrgyz (Kyrgyzstan)',
136
- 'lt' => 'Lithuanian',
137
- 'lt-LT' => 'Lithuanian (Lithuania)',
138
- 'lv' => 'Latvian',
139
- 'lv-LV' => 'Latvian (Latvia)',
140
- 'mi' => 'Maori',
141
- 'mi-NZ' => 'Maori (New Zealand)',
142
- 'mk' => 'FYRO Macedonian',
143
- 'mk-MK' => 'FYRO Macedonian (Former Yugoslav Republic of Macedonia)',
144
- 'mn' => 'Mongolian',
145
- 'mn-MN' => 'Mongolian (Mongolia)',
146
- 'mr' => 'Marathi',
147
- 'mr-IN' => 'Marathi (India)',
148
- 'ms' => 'Malay',
149
- 'ms-BN' => 'Malay (Brunei Darussalam)',
150
- 'ms-MY' => 'Malay (Malaysia)',
151
- 'mt' => 'Maltese',
152
- 'mt-MT' => 'Maltese (Malta)',
153
- 'nb' => 'Norwegian (Bokm?l)',
154
- 'nb-NO' => 'Norwegian (Bokm?l) (Norway)',
155
- 'nl' => 'Dutch',
156
- 'nl-BE' => 'Dutch (Belgium)',
157
- 'nl-NL' => 'Dutch (Netherlands)',
158
- 'nn-NO' => 'Norwegian (Nynorsk) (Norway)',
159
- 'ns' => 'Northern Sotho',
160
- 'ns-ZA' => 'Northern Sotho (South Africa)',
161
- 'pa' => 'Punjabi',
162
- 'pa-IN' => 'Punjabi (India)',
163
- 'pl' => 'Polish',
164
- 'pl-PL' => 'Polish (Poland)',
165
- 'ps' => 'Pashto',
166
- 'ps-AR' => 'Pashto (Afghanistan)',
167
- 'pt' => 'Portuguese',
168
- 'pt-BR' => 'Portuguese (Brazil)',
169
- 'pt-PT' => 'Portuguese (Portugal)',
170
- 'qu' => 'Quechua',
171
- 'qu-BO' => 'Quechua (Bolivia)',
172
- 'qu-EC' => 'Quechua (Ecuador)',
173
- 'qu-PE' => 'Quechua (Peru)',
174
- 'ro' => 'Romanian',
175
- 'ro-RO' => 'Romanian (Romania)',
176
- 'ru' => 'Russian',
177
- 'ru-RU' => 'Russian (Russia)',
178
- 'sa' => 'Sanskrit',
179
- 'sa-IN' => 'Sanskrit (India)',
180
- 'se' => 'Sami (Northern)',
181
- 'se-FI' => 'Sami (Northern) (Finland)',
182
- 'se-NO' => 'Sami (Northern) (Norway)',
183
- 'se-SE' => 'Sami (Lule) (Sweden)',
184
- 'sk' => 'Slovak',
185
- 'sk-SK' => 'Slovak (Slovakia)',
186
- 'sl' => 'Slovenian',
187
- 'sl-SI' => 'Slovenian (Slovenia)',
188
- 'sq' => 'Albanian',
189
- 'sq-AL' => 'Albanian (Albania)',
190
- 'sr-BA' => 'Serbian (Latin) (Bosnia and Herzegovina)',
191
- 'sr-SP' => 'Serbian (Latin) (Serbia and Montenegro)',
192
- 'sv' => 'Swedish',
193
- 'sv-FI' => 'Swedish (Finland)',
194
- 'sv-SE' => 'Swedish (Sweden)',
195
- 'sw' => 'Swahili',
196
- 'sw-KE' => 'Swahili (Kenya)',
197
- 'syr' => 'Syriac',
198
- 'syr-SY' => 'Syriac (Syria)',
199
- 'ta' => 'Tamil',
200
- 'ta-IN' => 'Tamil (India)',
201
- 'te' => 'Telugu',
202
- 'te-IN' => 'Telugu (India)',
203
- 'th' => 'Thai',
204
- 'th-TH' => 'Thai (Thailand)',
205
- 'tl' => 'Tagalog',
206
- 'tl-PH' => 'Tagalog (Philippines)',
207
- 'tn' => 'Tswana',
208
- 'tn-ZA' => 'Tswana (South Africa)',
209
- 'tr' => 'Turkish',
210
- 'tr-TR' => 'Turkish (Turkey)',
211
- 'tt' => 'Tatar',
212
- 'tt-RU' => 'Tatar (Russia)',
213
- 'ts' => 'Tsonga',
214
- 'uk' => 'Ukrainian',
215
- 'uk-UA' => 'Ukrainian (Ukraine)',
216
- 'ur' => 'Urdu',
217
- 'ur-PK' => 'Urdu (Islamic Republic of Pakistan)',
218
- 'uz' => 'Uzbek (Latin)',
219
- 'uz-UZ' => 'Uzbek (Cyrillic) (Uzbekistan)',
220
- 'vi' => 'Vietnamese',
221
- 'vi-VN' => 'Vietnamese (Viet Nam)',
222
- 'xh' => 'Xhosa',
223
- 'xh-ZA' => 'Xhosa (South Africa)',
224
- 'zh' => 'Chinese',
225
- 'zh-CN' => 'Chinese (S)',
226
- 'zh-HK' => 'Chinese (Hong Kong)',
227
- 'zh-MO' => 'Chinese (Macau)',
228
- 'zh-SG' => 'Chinese (Singapore)',
229
- 'zh-TW' => 'Chinese (T)',
230
- 'zu' => 'Zulu',
231
- 'zu-ZA' => 'Zulu (South Africa)'
232
- }.freeze
233
-
234
3
  def self.all
235
- ALL
4
+ @all ||= YAML.load(File.read(Hello.root.join('lib/data/locales.yml')))
236
5
  end
237
6
  end
238
7
  end