rack-locale-root-redirect 0.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +12 -1
- data/LICENSE.md +1 -1
- data/README.md +21 -20
- data/lib/rack/locale_root_redirect/middleware.rb +26 -7
- data/lib/rack/locale_root_redirect/version.rb +1 -1
- data/rack-locale-root-redirect.gemspec +1 -2
- data/spec/rack/locale_root_redirect_spec.rb +29 -14
- data/spec/spec_helper.rb +13 -3
- metadata +16 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d2d5a0277e85cb40191e22c43805c04c61686b6
|
4
|
+
data.tar.gz: ff459afe51d1e6f138e6b8b993b1278afdd2b6d6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5917d7929baaa7ba25c09cd9d23a06f4b09bb03cdb355f5c0283f9745cde0614484693c7547f2b6ef487e2a7e18933d2de53273654feab94b94befbb6bd02737
|
7
|
+
data.tar.gz: c94307202a975a43d1dc18573700573cbdad25e1c36640ca1a6d7e7bf51e4538ef1f9bb133584d501f94432df48dd8aff29deb53ab549ed9cedce8a44a8680a3
|
data/.travis.yml
CHANGED
@@ -1,7 +1,18 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
3
|
rvm:
|
4
|
-
- 2.
|
4
|
+
- 2.1
|
5
|
+
- 2.0
|
5
6
|
- 1.9.3
|
6
7
|
|
8
|
+
sudo: false
|
9
|
+
|
7
10
|
script: "echo 'DO IT' && bundle exec rake spec"
|
11
|
+
|
12
|
+
notifications:
|
13
|
+
hipchat:
|
14
|
+
rooms:
|
15
|
+
secure: "RFgHPxn6Oq4BSmmb9sI0Qd3lhDerpbuIUh6A08k0jB1WHTSUVMH62up/B33PGbvtdsCZ1vZwrFo/ePE7kZrRJSGHNoV55em7GsVBOqXRcJnl8YTj65IXM51S7d22v9YmhjG2mkyJo+IZ+yWTJ6DZI1DLqNmYWhszTvcJqWJOEd4="
|
16
|
+
template:
|
17
|
+
- '%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message} (<a href="%{build_url}">Build</a>/<a href="%{compare_url}">Changes</a>)'
|
18
|
+
format: 'html'
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# Rack::LocaleRootRedirect
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/mirego/rack-locale-root-redirect.png?branch=master)](https://travis-ci.org/mirego/rack-locale-root-redirect)
|
4
|
-
[![Coverage Status](https://coveralls.io/repos/mirego/rack-locale-root-redirect/badge.png)](https://coveralls.io/r/mirego/rack-locale-root-redirect)
|
5
4
|
[![Ruby Gem](https://badge.fury.io/rb/rack-locale-root-redirect.png)](https://rubygems.org/gems/microscope)
|
6
5
|
|
7
6
|
`Rack::LocaleRootRedirect` redirects requests to `"/"` based on the `Accept-Language` HTTP header.
|
@@ -22,48 +21,50 @@ $ bundle
|
|
22
21
|
|
23
22
|
## Usage
|
24
23
|
|
25
|
-
|
24
|
+
Add the `rack-locale-root-redirect` gem in your `Gemfile`.
|
26
25
|
|
27
26
|
```ruby
|
28
|
-
# Gemfile
|
29
|
-
gem 'sinatra'
|
30
27
|
gem 'rack-locale-root-redirect'
|
28
|
+
```
|
29
|
+
|
30
|
+
### With Ruby on Rails
|
31
|
+
|
32
|
+
Add these lines in your `config/application.rb` file, along other configuration instructions.
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
```ruby
|
35
|
+
config.use Rack::Accept
|
36
|
+
config.use Rack::LocaleRootRedirect, fr: '/fr', en: '/en'
|
37
|
+
```
|
35
38
|
|
36
|
-
|
37
|
-
use Rack::Accept
|
38
|
-
use Rack::LocaleRootRedirect, fr: "/fr", en: "/en"
|
39
|
+
### With Sinatra
|
39
40
|
|
40
|
-
|
41
|
-
get('/en') { 'English!' }
|
42
|
-
end
|
41
|
+
Add these lines in your `config.ru` file, or wherever your Sinatra application is located.
|
43
42
|
|
44
|
-
|
43
|
+
```ruby
|
44
|
+
use Rack::Accept
|
45
|
+
use Rack::LocaleRootRedirect, fr: '/fr', en: '/en'
|
45
46
|
```
|
46
47
|
|
47
|
-
|
48
|
+
### The result
|
48
49
|
|
49
50
|
```shell
|
50
51
|
$ rackup &
|
51
52
|
|
52
53
|
$ curl -sI "http://0.0.0.0:9292" -H "Accept-Language: fr;q=1, en;q=0.8" | grep "302\|Location"
|
53
|
-
HTTP/1.1 302
|
54
|
+
HTTP/1.1 302 Found
|
54
55
|
Location: /fr
|
55
56
|
|
56
57
|
$ curl -sI "http://0.0.0.0:9292" -H "Accept-Language: fr;q=0.4, en;q=0.8" | grep "302\|Location"
|
57
|
-
HTTP/1.1 302
|
58
|
+
HTTP/1.1 302 Found
|
58
59
|
Location: /en
|
59
60
|
```
|
60
61
|
|
61
62
|
## License
|
62
63
|
|
63
|
-
`Rack::LocaleRootRedirect` is © 2013 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/rack-locale-root-redirect/blob/master/LICENSE.md) file.
|
64
|
+
`Rack::LocaleRootRedirect` is © 2013-2015 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/rack-locale-root-redirect/blob/master/LICENSE.md) file.
|
64
65
|
|
65
66
|
## About Mirego
|
66
67
|
|
67
|
-
Mirego is a team of passionate people who believe that work is a place where you can innovate and have fun. We
|
68
|
+
[Mirego](http://mirego.com) is a team of passionate people who believe that work is a place where you can innovate and have fun. We're a team of [talented people](http://life.mirego.com) who imagine and build beautiful Web and mobile applications. We come together to share ideas and [change the world](http://mirego.org).
|
68
69
|
|
69
|
-
We also love
|
70
|
+
We also [love open-source software](http://open.mirego.com) and we try to give back to the community as much as we can.
|
@@ -1,24 +1,29 @@
|
|
1
|
-
require 'rack/accept'
|
2
|
-
|
3
1
|
module Rack
|
4
2
|
class LocaleRootRedirect
|
3
|
+
STATUS = 302
|
4
|
+
REGEX = %r[\A/(?<query_string>\?.*|\Z)]
|
5
|
+
RACK_ACCEPT_MISSING = 'Rack::LocaleRootRedirect must be used after Rack::Accept. Please make your application use Rack::Accept before Rack::LocaleRootRedirect.'
|
6
|
+
|
7
|
+
# @private
|
5
8
|
def initialize(app, locales = {})
|
6
9
|
@locales = locales
|
7
10
|
@available_locales = locales.keys.map(&:to_s)
|
8
11
|
@default_locale = @available_locales.first
|
12
|
+
|
9
13
|
@app = app
|
10
14
|
end
|
11
15
|
|
16
|
+
# @private
|
12
17
|
def call(env)
|
13
18
|
status, headers, response = @app.call(env)
|
14
19
|
|
15
20
|
if root_request?(env)
|
16
|
-
|
17
|
-
redirect_lang = language_matcher.best_of(@available_locales) || @default_locale
|
21
|
+
locale = best_locale(env)
|
18
22
|
|
19
|
-
status =
|
23
|
+
status = STATUS
|
20
24
|
query_string = env['QUERY_STRING'] == '' ? '' : "?#{env['QUERY_STRING']}"
|
21
|
-
headers['
|
25
|
+
headers['Vary'] = 'Accept-Language'
|
26
|
+
headers['Location'] = @locales[locale.to_sym] + query_string
|
22
27
|
end
|
23
28
|
|
24
29
|
[status, headers, response]
|
@@ -26,8 +31,22 @@ module Rack
|
|
26
31
|
|
27
32
|
protected
|
28
33
|
|
34
|
+
# Return whether we must act on this request
|
29
35
|
def root_request?(env)
|
30
|
-
|
36
|
+
REGEX.match(env['PATH_INFO'])
|
37
|
+
end
|
38
|
+
|
39
|
+
# Return the best locale to redirect to based on the request enviroment
|
40
|
+
def best_locale(env)
|
41
|
+
if accept = env['rack-accept.request']
|
42
|
+
matcher = accept.language.tap do |matcher|
|
43
|
+
matcher.first_level_match = true
|
44
|
+
end
|
45
|
+
|
46
|
+
matcher.best_of(@available_locales) || @default_locale
|
47
|
+
else
|
48
|
+
raise StandardError.new(RACK_ACCEPT_MISSING)
|
49
|
+
end
|
31
50
|
end
|
32
51
|
end
|
33
52
|
end
|
@@ -20,7 +20,6 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.add_runtime_dependency 'rack-accept', '>= 0.4.5'
|
22
22
|
|
23
|
-
gem.add_development_dependency 'rspec', '~>
|
24
|
-
gem.add_development_dependency 'coveralls'
|
23
|
+
gem.add_development_dependency 'rspec', '~> 3.1'
|
25
24
|
gem.add_development_dependency 'rake'
|
26
25
|
end
|
@@ -2,26 +2,41 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Rack::LocaleRootRedirect do
|
4
4
|
let(:app) { proc{[200,{},['Hello, world.']]} }
|
5
|
-
let(:stack) { Rack::LocaleRootRedirect.new(Rack::Accept.new(app), locales) }
|
6
5
|
let(:request) { Rack::MockRequest.new(stack) }
|
7
6
|
|
8
|
-
|
9
|
-
let(:
|
10
|
-
let(:response) { request.get('/?foo=bar', 'HTTP_ACCEPT_LANGUAGE' => accept_language.join(',')) }
|
7
|
+
context 'with stack using Rack::Accept' do
|
8
|
+
let(:stack) { Rack::LocaleRootRedirect.new(Rack::Accept.new(app), locales) }
|
11
9
|
|
12
|
-
|
13
|
-
let(:
|
14
|
-
|
15
|
-
|
10
|
+
describe 'response' do
|
11
|
+
let(:locales) { { fr: '/fr', en: '/en' } }
|
12
|
+
let(:response) { request.get('/?foo=bar', 'HTTP_ACCEPT_LANGUAGE' => accept_language.join(',')) }
|
13
|
+
|
14
|
+
context 'with first matching language' do
|
15
|
+
let(:accept_language) { %w{en es;q=0.9} }
|
16
|
+
it { expect(response.headers['Location']).to eq '/en?foo=bar' }
|
17
|
+
it { expect(response.headers['Vary']).to eq 'Accept-Language'}
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with second matching language' do
|
21
|
+
let(:accept_language) { %w{es en;q=0.8} }
|
22
|
+
it { expect(response.headers['Location']).to eq '/en?foo=bar' }
|
23
|
+
it { expect(response.headers['Vary']).to eq 'Accept-Language'}
|
24
|
+
end
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
|
26
|
+
context 'with default matching language' do
|
27
|
+
let(:accept_language) { %w{es jp;q=0.8} }
|
28
|
+
it { expect(response.headers['Location']).to eq '/fr?foo=bar' }
|
29
|
+
it { expect(response.headers['Vary']).to eq 'Accept-Language'}
|
30
|
+
end
|
20
31
|
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with stack without Rack::Accept' do
|
35
|
+
let(:locales) { { fr: '/fr', en: '/en' } }
|
36
|
+
let(:stack) { Rack::LocaleRootRedirect.new(app, locales) }
|
21
37
|
|
22
|
-
|
23
|
-
|
24
|
-
it { expect(response.headers['Location']).to eq '/fr?foo=bar' }
|
38
|
+
specify do
|
39
|
+
expect { request.get('/') }.to raise_error(StandardError, Rack::LocaleRootRedirect::RACK_ACCEPT_MISSING)
|
25
40
|
end
|
26
41
|
end
|
27
42
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
$:.unshift File.expand_path('../lib', __FILE__)
|
2
2
|
|
3
|
-
|
4
|
-
Coveralls.wear!
|
5
|
-
|
3
|
+
# We test using RSpec
|
6
4
|
require 'rspec'
|
5
|
+
|
6
|
+
# We need Rack::MockRequest
|
7
|
+
require 'rack/mock'
|
8
|
+
|
9
|
+
# Rack::LocaleRootRedirect requires Rack::Accept
|
10
|
+
require 'rack/accept'
|
11
|
+
|
12
|
+
# We need Rack::LocaleRootRedirect
|
7
13
|
require 'rack-locale-root-redirect'
|
8
14
|
|
9
15
|
RSpec.configure do |config|
|
16
|
+
# Disable `should` syntax
|
17
|
+
config.expect_with :rspec do |c|
|
18
|
+
c.syntax = :expect
|
19
|
+
end
|
10
20
|
end
|
metadata
CHANGED
@@ -1,69 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-locale-root-redirect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rémi Prévost
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack-accept
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.4.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.4.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '3.1'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: coveralls
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
40
|
+
version: '3.1'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rake
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- -
|
45
|
+
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: '0'
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- -
|
52
|
+
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
55
|
description: Rack::LocaleRootRedirect uses Rack:Accept to map '/' to a path based
|
@@ -74,9 +60,9 @@ executables: []
|
|
74
60
|
extensions: []
|
75
61
|
extra_rdoc_files: []
|
76
62
|
files:
|
77
|
-
- .gitignore
|
78
|
-
- .rspec
|
79
|
-
- .travis.yml
|
63
|
+
- ".gitignore"
|
64
|
+
- ".rspec"
|
65
|
+
- ".travis.yml"
|
80
66
|
- Gemfile
|
81
67
|
- LICENSE.md
|
82
68
|
- README.md
|
@@ -97,17 +83,17 @@ require_paths:
|
|
97
83
|
- lib
|
98
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
99
85
|
requirements:
|
100
|
-
- -
|
86
|
+
- - ">="
|
101
87
|
- !ruby/object:Gem::Version
|
102
88
|
version: '0'
|
103
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
90
|
requirements:
|
105
|
-
- -
|
91
|
+
- - ">="
|
106
92
|
- !ruby/object:Gem::Version
|
107
93
|
version: '0'
|
108
94
|
requirements: []
|
109
95
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.
|
96
|
+
rubygems_version: 2.2.2
|
111
97
|
signing_key:
|
112
98
|
specification_version: 4
|
113
99
|
summary: Rack::LocaleRootRedirect uses Rack:Accept to map '/' to a path based on the
|