locale_setter 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +19 -0
  4. data/Gemfile +19 -1
  5. data/README.md +44 -27
  6. data/Rakefile +67 -4
  7. data/lib/locale_setter.rb +28 -1
  8. data/lib/locale_setter/configuration.rb +8 -0
  9. data/lib/locale_setter/{rails.rb → controller.rb} +6 -6
  10. data/lib/locale_setter/domain.rb +17 -0
  11. data/lib/locale_setter/generic.rb +11 -5
  12. data/lib/locale_setter/railtie.rb +17 -0
  13. data/lib/locale_setter/user.rb +15 -6
  14. data/lib/locale_setter/version.rb +1 -1
  15. data/locale_setter.gemspec +1 -0
  16. data/spec/dummy/.rspec +2 -0
  17. data/spec/dummy/Rakefile +7 -0
  18. data/spec/dummy/app/controllers/application_controller.rb +16 -0
  19. data/spec/dummy/app/controllers/articles_controller.rb +9 -0
  20. data/spec/dummy/app/controllers/users_controller.rb +9 -0
  21. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  22. data/spec/dummy/app/models/article.rb +2 -0
  23. data/spec/dummy/app/models/user.rb +2 -0
  24. data/spec/dummy/app/views/_form.html.erb +25 -0
  25. data/spec/dummy/app/views/articles/_form.html.erb +25 -0
  26. data/spec/dummy/app/views/articles/edit.html.erb +6 -0
  27. data/spec/dummy/app/views/articles/index.html.erb +7 -0
  28. data/spec/dummy/app/views/articles/new.html.erb +5 -0
  29. data/spec/dummy/app/views/articles/show.html.erb +15 -0
  30. data/spec/dummy/app/views/edit.html.erb +6 -0
  31. data/spec/dummy/app/views/index.html.erb +25 -0
  32. data/spec/dummy/app/views/layouts/application.html.erb +11 -0
  33. data/spec/dummy/app/views/new.html.erb +5 -0
  34. data/spec/dummy/app/views/show.html.erb +15 -0
  35. data/spec/dummy/bin/rails +4 -0
  36. data/spec/dummy/config.ru +4 -0
  37. data/spec/dummy/config/application.rb +68 -0
  38. data/spec/dummy/config/boot.rb +5 -0
  39. data/spec/dummy/config/database.yml +25 -0
  40. data/spec/dummy/config/environment.rb +5 -0
  41. data/spec/dummy/config/environments/development.rb +33 -0
  42. data/spec/dummy/config/environments/production.rb +57 -0
  43. data/spec/dummy/config/environments/test.rb +31 -0
  44. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  45. data/spec/dummy/config/initializers/inflections.rb +15 -0
  46. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  47. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  48. data/spec/dummy/config/initializers/session_store.rb +8 -0
  49. data/spec/dummy/config/locales/arr.yml +2 -0
  50. data/spec/dummy/config/locales/en.yml +2 -0
  51. data/spec/dummy/config/locales/http.yml +2 -0
  52. data/spec/dummy/config/locales/user.yml +2 -0
  53. data/spec/dummy/config/mongoid.yml +80 -0
  54. data/spec/dummy/config/routes.rb +4 -0
  55. data/spec/dummy/db/migrate/20121019115657_create_posts.rb +8 -0
  56. data/spec/dummy/db/schema.rb +30 -0
  57. data/spec/dummy/db/seeds.rb +1 -0
  58. data/spec/dummy/lib/tasks/test.rake +16 -0
  59. data/spec/dummy/public/404.html +26 -0
  60. data/spec/dummy/public/422.html +26 -0
  61. data/spec/dummy/public/500.html +25 -0
  62. data/spec/dummy/public/favicon.ico +0 -0
  63. data/spec/dummy/script/rails +6 -0
  64. data/spec/{locale/rails_spec.rb → locale_setter/controller_spec.rb} +6 -6
  65. data/spec/locale_setter/domain_spec.rb +19 -0
  66. data/spec/{locale → locale_setter}/generic_spec.rb +16 -7
  67. data/spec/{locale → locale_setter}/http_spec.rb +0 -0
  68. data/spec/locale_setter/locale_setter_spec.rb +28 -0
  69. data/spec/{locale → locale_setter}/matcher_spec.rb +0 -0
  70. data/spec/{locale → locale_setter}/user_spec.rb +0 -0
  71. data/spec/request_helper.rb +8 -0
  72. data/spec/requests/request_spec.rb +43 -0
  73. data/spec/support/dummy_app.rb +85 -0
  74. data/spec/support/matchers/have_text.rb +50 -0
  75. metadata +142 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2177a5b71ff691ac29241b327d2deaef3456e08e
4
- data.tar.gz: 0fbf15da496596204083077d5c622441cd5dcf9c
3
+ metadata.gz: 78392b8ccf55802f8c105dc3c5bbcc3d3a0f3091
4
+ data.tar.gz: 8606c55302e4709c6d6f5627ebd186b8fa95d7a2
5
5
  SHA512:
6
- metadata.gz: ed37ab8f9b5ec6ac8527c8a53ed535d1a4f6ac05b9fa9283c4d9ad67e02da60696fa32c7d3d968578d24523d9fb92ef97bd3c3f04cc6a173949786216efa4763
7
- data.tar.gz: da77e1502788c59d1eb1713f0bdf53366795ef5a0f020057364b9383eb4f1be3b40470f407d7cd24a7a37e539c533bd5414fd3e10e007ead9fc161f75fc117cd
6
+ metadata.gz: a7a12f4611a7a7dccba46e757b13a5ce375d32554a8ee47223815285f7c29faafdc41728c120aa8521f11203a1c37c527ed7fb8c20b808eb82bd120fecc9b587
7
+ data.tar.gz: 69ef6e19e8cb639ea04663e6a1f411d0231b949d8668f80ebee39f2a149e35751169dd0926d3904e9eeac369025b370399dc31251a1278e4a2eb35a1347e8eb2
data/.gitignore CHANGED
@@ -15,3 +15,5 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ spec/dummy/log
19
+ spec/dummy/db/*.sqlite3
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ env:
8
+ - "RAILS_VERSION=3.2"
9
+ - "RAILS_VERSION=master"
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: 2.0.0
13
+ - env: "RAILS_VERSION=master"
14
+ exclude:
15
+ - rvm: 1.8.7
16
+ env: "RAILS_VERSION=master"
17
+ - rvm: 1.9.2
18
+ env: "RAILS_VERSION=master"
19
+
data/Gemfile CHANGED
@@ -3,4 +3,22 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in locale_setter.gemspec
4
4
  gemspec
5
5
 
6
- gem 'rspec'
6
+ platforms :ruby do
7
+ gem "sqlite3"
8
+ end
9
+
10
+ platforms :jruby do
11
+ gem "minitest", ">= 3.0"
12
+ gem "activerecord-jdbcsqlite3-adapter"
13
+ end
14
+
15
+ version = ENV["RAILS_VERSION"] || "3.2"
16
+
17
+ rails = case version
18
+ when "master"
19
+ {:github => "rails/rails"}
20
+ else
21
+ "~> #{version}.0"
22
+ end
23
+
24
+ gem "rails", rails
data/README.md CHANGED
@@ -1,9 +1,14 @@
1
1
  # LocaleSetter
2
2
 
3
- `LocaleSetter` sets the locale for the current request in a Rails application.
3
+ `LocaleSetter` sets the locale for the current request in a web application.
4
+ Rails has automatic support, other applications can use LocaleSetter with a
5
+ bit of configuration.
4
6
 
5
7
  ## Installation
6
8
 
9
+ Currently, LocaleSetter only supports Rails 3.2 and up. If you want 3.0 or
10
+ 3\.1 support, please file an Issue and we can work it out.
11
+
7
12
  ### Gem Installation
8
13
 
9
14
  Add this line to your application's Gemfile:
@@ -20,17 +25,7 @@ $ bundle
20
25
 
21
26
  ### Rails Application Configuration
22
27
 
23
- Include the module in your `app/controllers/application_controller.rb`:
24
-
25
- ```ruby
26
- class ApplicationController < ActionController::Base
27
- protect_from_forgery
28
-
29
- include LocaleSetter::Rails
30
- end
31
- ```
32
-
33
- *Note:* If you have before filters or a module that handles user authentication, have that _above_ this new `include` so it happens first.
28
+ There is none! Thanks, Railties!
34
29
 
35
30
  ### Non-Rails Applications
36
31
 
@@ -41,16 +36,17 @@ The library can be used outside of Rails by accessing `LocaleSetter::Generic` di
41
36
  request = {'HTTP_ACCEPT_LANGUAGE' = 'en,es;0.6'}
42
37
  params = {:locale = 'en'}
43
38
  user = User.first
44
- i18n = I18n
39
+ i18n = I18n
45
40
 
46
41
  # Set the .locale of I18n
47
42
  LocaleSetter::Generic.set_locale(i18n,
48
43
  {:env => request,
49
44
  :params => params,
50
- :user => user})
45
+ :user => user,
46
+ :domain => domain})
51
47
  ```
52
48
 
53
- The `i18n.locale=` will be called with the local selected from the passed data. `:env`, `:params`, and `:user` are all optional.
49
+ The `i18n.locale=` will be called with the local selected from the passed data. `:env`, `:params`, `:domain` and `:user` are all optional.
54
50
 
55
51
  ## How It Works
56
52
 
@@ -58,14 +54,31 @@ One of the challenges with internationalization is knowing which locale a user a
58
54
 
59
55
  1. URL Parameter
60
56
  2. User Preference
61
- 3. HTTP Headers
62
- 4. Default
57
+ 3. Domain Specific
58
+ 4. HTTP Headers
59
+ 5. Default
60
+
61
+ ### Configuration
62
+
63
+ `LocaleSetter` can be configured via a block. Here are the defaults:
64
+
65
+ ```ruby
66
+ LocaleSetter.configure do |config|
67
+ config.url_param = :locale
68
+ config.user_locale_method = :locale
69
+ config.localized_domains = {}
70
+ config.current_user_method = :current_user
71
+ end
72
+ ```
73
+
74
+ So if you want to change the defaults then call this method any time after
75
+ the library is loaded, like in a Rails initializer.
63
76
 
64
77
  ### URL Parameter
65
78
 
66
79
  As a developer or designer, it's incredibly handy to be able to manipulate the URL to change locales. You might even use this with CI to run your integration tests using each locale you support.
67
80
 
68
- If you're currently using the default locale for the application, generated URLs on your site will be untouched.
81
+ If you're currently using the default locale for the application, generated URLs on your site will be untouched.
69
82
 
70
83
  For example, say my default is `:en` for English and I am viewing in English, my URL might look like:
71
84
 
@@ -105,7 +118,7 @@ http://example.com/articles/1&locale=es
105
118
 
106
119
  #### Non-Supported Locales
107
120
 
108
- If the locale specified in the URL is not supported, `LocaleSetter` will revert to the default locale.
121
+ If the locale specified in the URL is not supported, `LocaleSetter` will revert to the default locale.
109
122
 
110
123
  Note that care has been taken to prevent a symbol-table-overflow denial of service attack. Unsupported locales are not symbolized, so there is no danger.
111
124
 
@@ -113,6 +126,8 @@ Note that care has been taken to prevent a symbol-table-overflow denial of servi
113
126
 
114
127
  If your system has authentication, then you likely use have a `current_user` helper method available. `LocaleSetter` will call `locale` on current user, expecting to get back a string response.
115
128
 
129
+ Both method names(`current_user` & `locale`) can be changed via a config block.
130
+
116
131
  #### Storing a User Preference
117
132
 
118
133
  The easiest solution is to add a column to your users table:
@@ -132,18 +147,20 @@ Then, allow them to edit this preference wherever they edit other profile items
132
147
 
133
148
  Remember that you may need to modify the `user.rb` if you're filtering mass-assignment parameters.
134
149
 
135
- #### Using a Different Method / Column
136
-
137
- `LocaleSetter::User` can be configured to call a method other than `.locale` on the user.
150
+ ### Locale-per-domain
138
151
 
139
- Anytime after the library is loaded, like in a Rails initializer, use the `locale_method=` method:
152
+ You could specify prefered locale according to the domain (or subdomain).
153
+ Just specify domains hash via config block:
140
154
 
141
155
  ```ruby
142
- LocaleSetter::User.locale_method = :my_locale
156
+ LocaleSetter.configure do |config|
157
+ config.localized_domains = {
158
+ "en.domain.com" => :en,
159
+ "es.domain.com" => :es
160
+ }
161
+ end
143
162
  ```
144
163
 
145
- Subsequent calls to `LocaleSetter::User.for` will use the specified method.
146
-
147
164
  ### HTTP Headers
148
165
 
149
166
  Every request coming into your web server includes a ton of header information. One key/value pair looks like this:
@@ -176,4 +193,4 @@ Check out https://github.com/jcasimir/locale_setter_test for a simple Rails appl
176
193
 
177
194
  ## License
178
195
 
179
- Please see the included LICENSE.txt
196
+ Please see the included LICENSE.txt
data/Rakefile CHANGED
@@ -1,6 +1,69 @@
1
- require "bundler/gem_tasks"
2
-
1
+ require 'rake'
2
+ require 'bundler/gem_tasks'
3
3
  require 'rspec/core/rake_task'
4
- RSpec::Core::RakeTask.new(:spec)
5
4
 
6
- task :default => :spec
5
+ def run_in_dummy_app(command)
6
+ success = system("cd spec/dummy && #{command}")
7
+ raise "#{command} failed" unless success
8
+ end
9
+
10
+ task "default" => "ci"
11
+
12
+ desc "Run all tests for CI"
13
+ task "ci" => "spec"
14
+
15
+ desc "Run all specs"
16
+ task "spec" => "spec:all"
17
+
18
+ namespace "spec" do
19
+ task "all" => ["locale_setter", "requests"]
20
+
21
+ def spec_task(name)
22
+ desc "Run #{name} specs"
23
+ RSpec::Core::RakeTask.new(name) do |t|
24
+ t.pattern = "spec/#{name}/**/*_spec.rb"
25
+ end
26
+ end
27
+
28
+ spec_task "locale_setter"
29
+
30
+ desc "Run request specs"
31
+ task "requests" => ["db:setup", "requests:all"]
32
+
33
+ namespace "requests" do
34
+ task "all" => ["development", "production", "test"]
35
+
36
+ ["development", "production"].each do |environment|
37
+ task environment do
38
+ Rake::Task["spec:requests:run"].execute environment
39
+ end
40
+ end
41
+
42
+ task "run" do |t, environment|
43
+ puts "Running request specs in #{environment}"
44
+
45
+ ENV["RAILS_ENV"] = environment
46
+ success = system("rspec spec/requests")
47
+
48
+ raise "Integration specs failed in #{environment}" unless success
49
+ end
50
+
51
+ task "test" do
52
+ puts "Running rake in dummy app"
53
+ ENV["RAILS_ENV"] = "test"
54
+ run_in_dummy_app "rake"
55
+ end
56
+ end
57
+ end
58
+
59
+ namespace "db" do
60
+ desc "Set up databases for integration testing"
61
+ task "setup" do
62
+ puts "Setting up databases"
63
+ run_in_dummy_app "rm -f db/*.sqlite3"
64
+ run_in_dummy_app "RAILS_ENV=development rake db:schema:load db:seed"
65
+ run_in_dummy_app "RAILS_ENV=production rake db:schema:load db:seed"
66
+ run_in_dummy_app "RAILS_ENV=test rake db:schema:load"
67
+ end
68
+ end
69
+
data/lib/locale_setter.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require "locale_setter/version"
2
+ require "locale_setter/configuration"
2
3
  require "locale_setter/matcher"
3
- require "locale_setter/rails"
4
+ require "locale_setter/controller"
5
+ require "locale_setter/railtie" if defined?(Rails)
4
6
  require "locale_setter/http"
5
7
  require "locale_setter/user"
8
+ require "locale_setter/domain"
6
9
  require "locale_setter/param"
7
10
  require "locale_setter/generic"
8
11
 
@@ -10,4 +13,28 @@ module LocaleSetter
10
13
  HTTP_HEADER = 'HTTP_ACCEPT_LANGUAGE'
11
14
  URL_PARAM = :locale
12
15
  USER_METHOD = :locale
16
+ CURRENT_USER_METHOD = :current_user
17
+
18
+ class << self
19
+ attr_accessor :configuration
20
+
21
+ def config
22
+ self.configuration ||= Configuration.new(default_params)
23
+ end
24
+
25
+ def configure
26
+ yield(config)
27
+ end
28
+
29
+ private
30
+
31
+ def default_params
32
+ {
33
+ :url_param => URL_PARAM,
34
+ :user_locale_method => USER_METHOD,
35
+ :localized_domains => {},
36
+ :current_user_method => CURRENT_USER_METHOD
37
+ }
38
+ end
39
+ end
13
40
  end
@@ -0,0 +1,8 @@
1
+ class Configuration
2
+ attr_accessor :url_param, :user_locale_method, :localized_domains,
3
+ :http_header, :current_user_method
4
+
5
+ def initialize(options)
6
+ options.each_pair { |k, v| send(:"#{k}=", v) }
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  module LocaleSetter
2
- module Rails
2
+ module Controller
3
3
  def self.included(controller)
4
4
  controller.before_filter :set_locale
5
5
  end
@@ -8,7 +8,7 @@ module LocaleSetter
8
8
  if i18n.locale == i18n.default_locale
9
9
  options
10
10
  else
11
- {URL_PARAM => i18n.locale}.merge(options)
11
+ {LocaleSetter.config.url_param => i18n.locale}.merge(options)
12
12
  end
13
13
  end
14
14
 
@@ -17,18 +17,18 @@ module LocaleSetter
17
17
  i18n,
18
18
  {:params => params,
19
19
  :user => locale_user,
20
+ :domain => request.domain,
20
21
  :env => request.env}
21
22
  )
22
23
  end
23
24
 
24
25
  def locale_user
25
- if respond_to?(:current_user) && current_user
26
- current_user
27
- end
26
+ current_user_method = LocaleSetter.config.current_user_method.to_sym
27
+ send(current_user_method) if respond_to?(current_user_method)
28
28
  end
29
29
 
30
30
  def i18n
31
31
  I18n
32
32
  end
33
33
  end
34
- end
34
+ end
@@ -0,0 +1,17 @@
1
+ module LocaleSetter
2
+ module Domain
3
+
4
+ def self.for(domain, available)
5
+ LocaleSetter::Matcher.match get_domain(domain), available
6
+ end
7
+
8
+ def self.get_domain(domain)
9
+ LocaleSetter.config.localized_domains[domain]
10
+ end
11
+
12
+ def self.localized_domains=(domains)
13
+ warn "Deprecation warning. You should use a new block syntax for configuration."
14
+ LocaleSetter.config.localized_domains = domains
15
+ end
16
+ end
17
+ end
@@ -3,11 +3,13 @@ module LocaleSetter
3
3
 
4
4
  def self.set_locale(i18n, options = {:params => nil,
5
5
  :user => nil,
6
+ :domain => nil,
6
7
  :env => nil})
7
8
 
8
- i18n.locale = from_params(options[:params], available(i18n)) ||
9
- from_user(options[:user], available(i18n)) ||
10
- from_http(options[:env], available(i18n)) ||
9
+ i18n.locale = from_params(options[:params], available(i18n)) ||
10
+ from_user(options[:user], available(i18n)) ||
11
+ from_domain(options[:domain], available(i18n)) ||
12
+ from_http(options[:env], available(i18n)) ||
11
13
  i18n.default_locale
12
14
  end
13
15
 
@@ -25,9 +27,13 @@ module LocaleSetter
25
27
  end
26
28
  end
27
29
 
30
+ def self.from_domain(domain, available)
31
+ LocaleSetter::Domain.for(domain, available)
32
+ end
33
+
28
34
  def self.from_params(params, available)
29
- if params && params[URL_PARAM]
30
- LocaleSetter::Param.for(params[URL_PARAM], available)
35
+ if params && params[LocaleSetter.config.url_param]
36
+ LocaleSetter::Param.for(params[LocaleSetter.config.url_param], available)
31
37
  end
32
38
  end
33
39
  end
@@ -0,0 +1,17 @@
1
+ require 'rails/railtie'
2
+
3
+ module LocaleSetter
4
+ class Railtie < Rails::Railtie
5
+ config.after_initialize do |app|
6
+ # I would prefer to do this in an initializer block, but it's important
7
+ # that we do this _before_ any of the user's authentication stuff
8
+ # happens. So this is the best we can get for now.
9
+ ApplicationController.send(:include, LocaleSetter::Controller)
10
+ end
11
+ end
12
+ module Rails
13
+ def self.included(controller)
14
+ ActiveSupport::Deprecation.warn("You don't need to include LocaleSetter::Rails any more. There's a Railtie for That (tm).")
15
+ end
16
+ end
17
+ end
@@ -1,20 +1,29 @@
1
+ # this is primarily for 1.8.7 support
2
+ # see http://www.ruby-doc.org/core-2.0/Symbol.html#method-i-empty-3F
3
+ unless :locale.respond_to? :empty?
4
+ class Symbol
5
+ def empty?
6
+ self.to_s.empty?
7
+ end
8
+ end
9
+ end
10
+
1
11
  module LocaleSetter
2
12
  module User
3
- @@user_locale_method = :locale
4
-
5
13
  def self.for(user, available)
6
- if user && user.respond_to?(locale_method) &&
14
+ if user && user.respond_to?(locale_method) &&
7
15
  user.send(locale_method) && !user.send(locale_method).empty?
8
16
  LocaleSetter::Matcher.match user.send(locale_method), available
9
17
  end
10
18
  end
11
19
 
12
20
  def self.locale_method
13
- @@user_locale_method
21
+ LocaleSetter.config.user_locale_method
14
22
  end
15
23
 
16
24
  def self.locale_method=(method_name)
17
- @@user_locale_method = method_name
25
+ warn "Deprecation warning. You should use a new block syntax for configuration."
26
+ LocaleSetter.config.user_locale_method = method_name
18
27
  end
19
28
  end
20
- end
29
+ end