panmind-http_accept_language 1.1.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/.gitignore +4 -0
- data/README.rdoc +44 -0
- data/Rakefile +37 -0
- data/VERSION +1 -0
- data/lib/http_accept_language.rb +89 -0
- data/rails/init.rb +1 -0
- data/test/http_accept_language_test.rb +55 -0
- metadata +75 -0
data/.gitignore
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
= HttpAcceptLanguage
|
2
|
+
|
3
|
+
A small effort in making a plugin which helps you detect the users preferred language, as sent by the HTTP header.
|
4
|
+
|
5
|
+
== Features
|
6
|
+
|
7
|
+
* Splits the http-header into languages specified by the user
|
8
|
+
* Returns empty array if header is illformed.
|
9
|
+
* Corrects case to xx-XX
|
10
|
+
* Sorted by priority given, as much as possible.
|
11
|
+
* Gives you the most important language
|
12
|
+
* Gives compatible languages
|
13
|
+
See also: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
14
|
+
|
15
|
+
== Example
|
16
|
+
|
17
|
+
class SomeController < ApplicationController
|
18
|
+
def some_action
|
19
|
+
|
20
|
+
request.user_preferred_languages
|
21
|
+
# => [ 'nl-NL', 'nl-BE', 'nl', 'en-US', 'en' ]
|
22
|
+
|
23
|
+
available = %w{en en-US nl-BE}
|
24
|
+
request.preferred_language_from(available)
|
25
|
+
# => 'nl-BE'
|
26
|
+
|
27
|
+
request.user_preferred_languages
|
28
|
+
# => [ 'en-GB']
|
29
|
+
available = %w{en-US}
|
30
|
+
request.compatible_language_from(available)
|
31
|
+
# => 'en-US'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
== Installation
|
36
|
+
|
37
|
+
Install the gem <tt>http_accept_language</tt>, require it in your Rails app.
|
38
|
+
|
39
|
+
== Changelog
|
40
|
+
|
41
|
+
* 2010-01-05: Gem release
|
42
|
+
* 2009-03-12: Rails 2.3 compatible
|
43
|
+
|
44
|
+
Copyright (c) 2008-2010 Iain Hecker, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'jeweler'
|
5
|
+
Jeweler::Tasks.new do |gem|
|
6
|
+
gem.name = "panmind-http_accept_language"
|
7
|
+
gem.summary = %Q{Parse the HTTP Accept Language Header}
|
8
|
+
gem.description = %Q{Find out which locale the user preferes by reading the languages they specified in their browser}
|
9
|
+
gem.email = "marcello.barnaba@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/Panmind/http_accept_language"
|
11
|
+
gem.authors = ["Iain Hecker", "Marcello Barnaba"]
|
12
|
+
end
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rake/testtask'
|
19
|
+
desc 'Test the http_accept_language plugin.'
|
20
|
+
Rake::TestTask.new(:test) do |t|
|
21
|
+
t.libs << 'lib'
|
22
|
+
t.pattern = 'test/**/*_test.rb'
|
23
|
+
t.verbose = true
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Default: run unit tests.'
|
27
|
+
task :default => :test
|
28
|
+
|
29
|
+
require 'rake/rdoctask'
|
30
|
+
desc 'Generate documentation for the http_accept_language plugin.'
|
31
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
32
|
+
rdoc.rdoc_dir = 'rdoc'
|
33
|
+
rdoc.title = 'HttpAcceptLanguage'
|
34
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
35
|
+
rdoc.rdoc_files.include('README')
|
36
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
37
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.1.0
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module HttpAcceptLanguage
|
2
|
+
|
3
|
+
# Returns a sorted array based on user preference in sent via
|
4
|
+
# the Accept-Language HTTP header. Don't think this is holy!
|
5
|
+
#
|
6
|
+
# Returns an empty array if the header does not contain any
|
7
|
+
# parsable language code.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
#
|
11
|
+
# Accept-Language: en;q=0.3, nl-NL, nl-be;q=0.9, en-US;q=0.5
|
12
|
+
#
|
13
|
+
# request.user_preferred_languages
|
14
|
+
# # => [ 'nl-NL', 'nl-BE', 'nl', 'en-US', 'en' ]
|
15
|
+
#
|
16
|
+
def user_preferred_languages
|
17
|
+
@user_preferred_languages ||= env['HTTP_ACCEPT_LANGUAGE']
|
18
|
+
.scan(/\b([a-z]{2}(?:-[a-z]{2})?)(?:;q=([01](?:\.\d)?))?\s*($|,)/)
|
19
|
+
.sort_by {|l, pref| 1 - (pref || 1).to_f}
|
20
|
+
.map! {|l,| l.downcase.sub(/-\w{2}/) { $&.upcase } }
|
21
|
+
|
22
|
+
rescue # Just rescue anything if the browser messed up badly.
|
23
|
+
[]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a sorted array of language codes symbols based on user's
|
27
|
+
# browser preference sent via the Accept-Language HTTP header.
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
#
|
31
|
+
# Accept-Language: en;q=0.3, nl-NL, nl-be;q=0.9, en-US;q=0.5
|
32
|
+
#
|
33
|
+
# request.user_preferred_languages
|
34
|
+
# # => [ :nl, :en ]
|
35
|
+
#
|
36
|
+
def user_preferred_language_codes
|
37
|
+
@user_preferred_language_codes ||=
|
38
|
+
strip_region_from user_preferred_languages
|
39
|
+
end
|
40
|
+
|
41
|
+
# Sets the user languages preference, overiding the browser
|
42
|
+
#
|
43
|
+
def user_preferred_languages=(languages)
|
44
|
+
@user_preferred_languages = languages
|
45
|
+
@user_preferred_language_codes = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns a preferred language from an array containing
|
49
|
+
# language codes with regions.
|
50
|
+
#
|
51
|
+
# Example:
|
52
|
+
#
|
53
|
+
# Accept-Language: en;q=0.3, nl-NL, nl-be;q=0.9, en-US;q=0.5
|
54
|
+
#
|
55
|
+
# request.preferred_language_from %w( it fr nl nl-NL )
|
56
|
+
# # => 'nl'
|
57
|
+
#
|
58
|
+
def preferred_language_from(array)
|
59
|
+
(user_preferred_languages & array.map(&:to_s)).first
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the first of the user_preferred_languages that
|
63
|
+
# is included into the given array, ignoring region.
|
64
|
+
#
|
65
|
+
# Useful with Rails' I18n.available_locales.
|
66
|
+
#
|
67
|
+
# Example:
|
68
|
+
#
|
69
|
+
# Accept-Language: en;q=0.3, nl-NL, nl-be;q=0.9, en-US;q=0.5
|
70
|
+
#
|
71
|
+
# request.compatible_language_from [:nl, :it]
|
72
|
+
# # => 'nl'
|
73
|
+
#
|
74
|
+
def compatible_language_from(array)
|
75
|
+
(user_preferred_language_codes & strip_region_from(array)).first
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def strip_region_from(languages)
|
80
|
+
languages.map {|l| l.to_s.sub(/-\w{2}/, '')}.uniq
|
81
|
+
end
|
82
|
+
end
|
83
|
+
if defined?(ActionDispatch::Request)
|
84
|
+
ActionDispatch::Request.send :include, HttpAcceptLanguage
|
85
|
+
elsif defined?(ActionDispatch::AbstractRequest)
|
86
|
+
ActionDispatch::AbstractRequest.send :include, HttpAcceptLanguage
|
87
|
+
elsif defined?(ActionDispatch::CgiRequest)
|
88
|
+
ActionDispatch::CgiRequest.send :include, HttpAcceptLanguage
|
89
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "http_accept_language"
|
@@ -0,0 +1,55 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
require 'http_accept_language'
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class MockedCgiRequest
|
6
|
+
include HttpAcceptLanguage
|
7
|
+
def env
|
8
|
+
@env ||= {'HTTP_ACCEPT_LANGUAGE' => 'it;q=0.4,en-us, en-gb;q=0.8,en;q=0.6, de;q=2, invalid;q=1, xx;q=30,, ., .'}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class HttpAcceptLanguageTest < Test::Unit::TestCase
|
13
|
+
def test_should_return_empty_array
|
14
|
+
request.env['HTTP_ACCEPT_LANGUAGE'] = nil
|
15
|
+
assert_equal [], request.user_preferred_languages
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_should_properly_split
|
19
|
+
assert_equal %w{en-US en-GB en it}, request.user_preferred_languages
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_ignore_jambled_header
|
23
|
+
request.env['HTTP_ACCEPT_LANGUAGE'] = 'odkhjf89fioma098jq .,.,'
|
24
|
+
assert_equal [], request.user_preferred_languages
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_find_first_available_language
|
28
|
+
assert_equal 'en-GB', request.preferred_language_from(%w{en en-GB})
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_find_first_compatible_language
|
32
|
+
assert_equal 'en', request.compatible_language_from(%w{en-hk en-GB en})
|
33
|
+
assert_equal 'it', request.compatible_language_from(%w{it de})
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_should_find_first_compatible_from_user_preferred
|
37
|
+
request.env['HTTP_ACCEPT_LANGUAGE'] = 'en-us,de-de'
|
38
|
+
assert_equal 'en', request.compatible_language_from(%w{de en})
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_should_find_first_compatible_from_user_preferred_in_order
|
42
|
+
request.env['HTTP_ACCEPT_LANGUAGE'] = 'de-de, en-us'
|
43
|
+
assert_equal 'de', request.compatible_language_from(%w{de en})
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_should_accept_symbols_as_available_languages
|
47
|
+
request.env['HTTP_ACCEPT_LANGUAGE'] = 'en-us'
|
48
|
+
assert_equal 'en', request.compatible_language_from([:en, :de])
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def request
|
53
|
+
@request ||= MockedCgiRequest.new
|
54
|
+
end
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: panmind-http_accept_language
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 1.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Iain Hecker
|
14
|
+
- Marcello Barnaba
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-09-27 00:00:00 +02:00
|
20
|
+
default_executable:
|
21
|
+
dependencies: []
|
22
|
+
|
23
|
+
description: Find out which locale the user preferes by reading the languages they specified in their browser
|
24
|
+
email: marcello.barnaba@gmail.com
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files:
|
30
|
+
- README.rdoc
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- README.rdoc
|
34
|
+
- Rakefile
|
35
|
+
- VERSION
|
36
|
+
- http_accept_language.gemspec
|
37
|
+
- lib/http_accept_language.rb
|
38
|
+
- rails/init.rb
|
39
|
+
- test/http_accept_language_test.rb
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/Panmind/http_accept_language
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options:
|
46
|
+
- --charset=UTF-8
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
hash: 3
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
hash: 3
|
64
|
+
segments:
|
65
|
+
- 0
|
66
|
+
version: "0"
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.3.7
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Parse the HTTP Accept Language Header
|
74
|
+
test_files:
|
75
|
+
- test/http_accept_language_test.rb
|