rack-i18n_locale_switcher 0.1.0 → 0.2.0
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.
- data/CHANGELOG +3 -0
- data/Rakefile +2 -2
- data/lib/rack/i18n_locale_switcher.rb +43 -31
- data/rack-i18n_locale_switcher.gemspec +4 -1
- data/spec/i18n_locale_switcher_spec.rb +66 -3
- metadata +16 -5
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
Echoe.new('rack-i18n_locale_switcher', '0.
|
5
|
+
Echoe.new('rack-i18n_locale_switcher', '0.2.0') do |p|
|
6
6
|
|
7
7
|
p.description = "Detects the current locale from url, domain, parameter, session or accept header."
|
8
8
|
p.url = "http://github.com/christoph-buente/rack-i18n_locale_switcher"
|
@@ -20,7 +20,7 @@ Echoe.new('rack-i18n_locale_switcher', '0.1.0') do |p|
|
|
20
20
|
*.tmproj
|
21
21
|
}
|
22
22
|
|
23
|
-
p.runtime_dependencies = [ "rack", "i18n" ]
|
23
|
+
p.runtime_dependencies = [ "rack", "i18n", "domainatrix" ]
|
24
24
|
p.development_dependencies = [ "echoe", "rspec", "rack-test" ]
|
25
25
|
end
|
26
26
|
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'i18n'
|
2
|
+
require 'domainatrix'
|
3
|
+
|
2
4
|
module Rack
|
3
5
|
class I18nLocaleSwitcher
|
4
6
|
def initialize(app, options = {})
|
@@ -6,24 +8,11 @@ module Rack
|
|
6
8
|
end
|
7
9
|
|
8
10
|
def call(env)
|
9
|
-
request = Rack::Request.new
|
11
|
+
request = Rack::Request.new(env)
|
10
12
|
|
11
13
|
session = request.session
|
12
|
-
locale =
|
13
|
-
|
14
|
-
if locale == I18n.default_locale
|
15
|
-
session["locale"] = locale
|
16
|
-
path = request.fullpath.gsub(/\/#{locale}\b/, '')
|
17
|
-
# ignore paths given with except option
|
18
|
-
unless request.fullpath =~ %r{/tolk/|/api/}
|
19
|
-
return [ 302, {'Location'=> "#{request.scheme}://#{request.host_with_port}#{path}" }, [] ]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
session["locale"] = locale if is_present?(locale)
|
24
|
-
session["locale"] = first_http_accept_language(env) unless is_present?(session["locale"])
|
25
|
-
|
26
|
-
I18n.locale = session["locale"]
|
14
|
+
locale = extract_locale(request)
|
15
|
+
I18n.locale = session["locale"] = (is_present?(locale) ? locale : I18n.default_locale)
|
27
16
|
|
28
17
|
@app.call cleanup_env(env)
|
29
18
|
end
|
@@ -45,39 +34,62 @@ module Rack
|
|
45
34
|
end
|
46
35
|
end
|
47
36
|
|
48
|
-
def
|
49
|
-
|
37
|
+
def extract_locale_from_tld(request)
|
38
|
+
locale = Domainatrix.parse(request.url).public_suffix rescue nil
|
39
|
+
locale if is_available?(locale)
|
50
40
|
end
|
51
41
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
42
|
+
def extract_locale_from_subdomain(request)
|
43
|
+
locale = Domainatrix.parse(request.url).subdomain rescue nil
|
44
|
+
locale if is_available?(locale)
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_locale_from_session(request)
|
48
|
+
locale = request.session['locale']
|
49
|
+
locale if is_available?(locale)
|
60
50
|
end
|
61
51
|
|
62
|
-
def
|
63
|
-
if lang = env["HTTP_ACCEPT_LANGUAGE"]
|
52
|
+
def extract_locale_from_accept_language(request)
|
53
|
+
if lang = request.env["HTTP_ACCEPT_LANGUAGE"]
|
64
54
|
lang = lang.split(",").map { |l|
|
65
55
|
l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
|
66
56
|
l.split(';q=')
|
67
57
|
}.first
|
68
58
|
locale = symbolize_locale(lang.first.split("-").first)
|
69
59
|
else
|
70
|
-
locale =
|
60
|
+
locale = I18n.default_locale
|
61
|
+
end
|
62
|
+
is_available?(locale) ? locale : I18n.default_locale
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def extract_locale(request)
|
67
|
+
locale = ( extract_locale_from_params(request) ||
|
68
|
+
extract_locale_from_path(request) ||
|
69
|
+
extract_locale_from_subdomain(request) ||
|
70
|
+
extract_locale_from_tld(request) ||
|
71
|
+
extract_locale_from_session(request) ||
|
72
|
+
extract_locale_from_accept_language(request))
|
73
|
+
symbolize_locale(locale)
|
74
|
+
end
|
75
|
+
|
76
|
+
def cleanup_env env
|
77
|
+
%w{REQUEST_URI REQUEST_PATH PATH_INFO}.each do |key|
|
78
|
+
if is_present?(env[key]) && env[key].length > 1 && tmp = env[key].split("/")
|
79
|
+
tmp.delete_at(1) if tmp[1] =~ %r{^([a-zA-Z]{2})$}
|
80
|
+
env[key] = tmp.join("/")
|
81
|
+
end
|
71
82
|
end
|
72
|
-
|
83
|
+
env
|
73
84
|
end
|
74
85
|
|
86
|
+
|
75
87
|
def is_present?(value)
|
76
88
|
!value.to_s.empty?
|
77
89
|
end
|
78
90
|
|
79
91
|
def symbolize_locale(locale)
|
80
|
-
is_present?(locale) ? locale.to_s.downcase.to_sym :
|
92
|
+
(is_present?(locale) ? locale.to_s.downcase.to_sym : nil)
|
81
93
|
end
|
82
94
|
|
83
95
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "rack-i18n_locale_switcher"
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Christoph B\u{fc}nte, Andreas Korth"]
|
@@ -24,12 +24,14 @@ Gem::Specification.new do |s|
|
|
24
24
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
25
|
s.add_runtime_dependency(%q<rack>, [">= 0"])
|
26
26
|
s.add_runtime_dependency(%q<i18n>, [">= 0"])
|
27
|
+
s.add_runtime_dependency(%q<domainatrix>, [">= 0"])
|
27
28
|
s.add_development_dependency(%q<echoe>, [">= 0"])
|
28
29
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
29
30
|
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
30
31
|
else
|
31
32
|
s.add_dependency(%q<rack>, [">= 0"])
|
32
33
|
s.add_dependency(%q<i18n>, [">= 0"])
|
34
|
+
s.add_dependency(%q<domainatrix>, [">= 0"])
|
33
35
|
s.add_dependency(%q<echoe>, [">= 0"])
|
34
36
|
s.add_dependency(%q<rspec>, [">= 0"])
|
35
37
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
@@ -37,6 +39,7 @@ Gem::Specification.new do |s|
|
|
37
39
|
else
|
38
40
|
s.add_dependency(%q<rack>, [">= 0"])
|
39
41
|
s.add_dependency(%q<i18n>, [">= 0"])
|
42
|
+
s.add_dependency(%q<domainatrix>, [">= 0"])
|
40
43
|
s.add_dependency(%q<echoe>, [">= 0"])
|
41
44
|
s.add_dependency(%q<rspec>, [">= 0"])
|
42
45
|
s.add_dependency(%q<rack-test>, [">= 0"])
|
@@ -2,6 +2,11 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe "Rack::I18nLocaleSwitcher" do
|
4
4
|
|
5
|
+
before do
|
6
|
+
I18n.available_locales = [:en, :'en-US', :de, :'de-DE', :es]
|
7
|
+
I18n.default_locale = :en
|
8
|
+
end
|
9
|
+
|
5
10
|
def app
|
6
11
|
Rack::Builder.new {
|
7
12
|
map "/" do
|
@@ -11,12 +16,70 @@ describe "Rack::I18nLocaleSwitcher" do
|
|
11
16
|
}.to_app
|
12
17
|
end
|
13
18
|
|
19
|
+
it "should set the locate to default locale" do
|
20
|
+
get '/'
|
21
|
+
I18n.locale.should eql(I18n.default_locale)
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'from request params' do
|
25
|
+
|
26
|
+
it "should set the I18n locale" do
|
27
|
+
get '/', :locale => 'de'
|
28
|
+
last_request.url.should include('?locale=de')
|
29
|
+
I18n.locale.should eql(:de)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should disallow other locales than the available locales" do
|
33
|
+
get '/', :locale => 'xx'
|
34
|
+
I18n.locale.should eql(I18n.default_locale)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'from path prefix ' do
|
40
|
+
it "should set the I18n locale" do
|
41
|
+
get '/de/'
|
42
|
+
I18n.locale.should eql(:de)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'from subdomain' do
|
47
|
+
|
48
|
+
it "should set the I18n locale" do
|
49
|
+
get 'http://de.example.com/'
|
50
|
+
I18n.locale.should eql(:de)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'from top level domain' do
|
55
|
+
|
56
|
+
|
57
|
+
it "should set the I18n locale" do
|
58
|
+
get 'http://example.de/'
|
59
|
+
I18n.locale.should eql(:de)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'from accept-language header' do
|
65
|
+
|
66
|
+
it "should override the client requested locale" do
|
67
|
+
get '/' , {}, {'HTTP_ACCEPT_LANGUAGE' => "de, de-de,en;q=0.5"}
|
68
|
+
I18n.locale.should eql(:de)
|
69
|
+
end
|
14
70
|
|
15
|
-
it "should detect locale from Accept-Language-Header" do
|
16
|
-
get '/', {'Accept-Language' => 'en-US, en'}
|
17
|
-
I18n.locale.should == :en
|
18
71
|
end
|
19
72
|
|
73
|
+
context 'from session' do
|
74
|
+
it "should set the locale to whatever locale is set in the session" do
|
75
|
+
|
76
|
+
get '/', {}, {'rack.session' => {'locale' => 'de'}}
|
77
|
+
I18n.locale.should eql(:de)
|
78
|
+
end
|
20
79
|
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'from default' do
|
83
|
+
end
|
21
84
|
|
22
85
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rack-i18n_locale_switcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- "Christoph B\xC3\xBCnte, Andreas Korth"
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id002
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
|
-
name:
|
38
|
+
name: domainatrix
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id003 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: "0"
|
46
|
-
type: :
|
46
|
+
type: :runtime
|
47
47
|
version_requirements: *id003
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
|
-
name:
|
49
|
+
name: echoe
|
50
50
|
prerelease: false
|
51
51
|
requirement: &id004 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
@@ -57,7 +57,7 @@ dependencies:
|
|
57
57
|
type: :development
|
58
58
|
version_requirements: *id004
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
|
-
name:
|
60
|
+
name: rspec
|
61
61
|
prerelease: false
|
62
62
|
requirement: &id005 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
@@ -67,6 +67,17 @@ dependencies:
|
|
67
67
|
version: "0"
|
68
68
|
type: :development
|
69
69
|
version_requirements: *id005
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rack-test
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
type: :development
|
80
|
+
version_requirements: *id006
|
70
81
|
description: Detects the current locale from url, domain, parameter, session or accept header.
|
71
82
|
email:
|
72
83
|
- info@christophbuente.de
|