diff --git a/README.md b/README.md index 65a502a..caf40af 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This Rails gem makes use of the HTTP_ACCEPT_LANGUAGE http header sent by web bro When this fails (for example if there is no such http header - as is the case for Google bot), it will try to determine the locale based on the toplevel domain suffix (so it will set `'de'` for the `example.de` domain). -When both fail, it will fall back to `I18n.default_locale`, which should be set in application’s `config/application.rb` file (and is `'en'` by default). +When both fail, it will fall back to `I18n.default_locale`, which should be set in application’s `config/application.rb` file (`'en'` by default). The HTTP_ACCEPT_LANGUAGE header parser is based on: https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language.rb @@ -47,5 +47,18 @@ $ bundle ``` +## Turning off the language autodetection + +In certain cases we might want to turn off the locale/language autodetection. For example, we might want to give the user the ability to set his preferred language in his profile and respect this setting. + +In order to do that, you need to set a `:language` session key in your app: + +```ruby +session[:language] = 'pl' +``` + +In consequence, regardless of the user browser’s language, the `I18n.locale` will be set to `'pl'`. + + Copyright © 2011 Exvo.com Development BV, released under the MIT license diff --git a/lib/locale_detector/filter.rb b/lib/locale_detector/filter.rb index 1764731..08d1c03 100644 --- a/lib/locale_detector/filter.rb +++ b/lib/locale_detector/filter.rb @@ -9,16 +9,22 @@ module Filter protected def set_locale - I18n.locale = begin - request.env['HTTP_ACCEPT_LANGUAGE'].split(/\s*,\s*/).collect do |l| - l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/ - l.split(';q=') - end.sort do |x,y| - raise "Incorrect format" unless x.first =~ /^[a-z\-]+$/i - y.last.to_f <=> x.last.to_f - end.first.first.gsub(/-[a-z]+$/i, '').downcase - rescue # rescue (anything) from the malformed (or missing) accept language headers - country_to_language(request.host.split('.').last) + if session[:language].present? + # set locale from session + I18n.locale = session[:language] + else + # set locale from http header or request host + I18n.locale = begin + request.env['HTTP_ACCEPT_LANGUAGE'].split(/\s*,\s*/).collect do |l| + l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/ + l.split(';q=') + end.sort do |x,y| + raise "Incorrect format" unless x.first =~ /^[a-z\-]+$/i + y.last.to_f <=> x.last.to_f + end.first.first.gsub(/-[a-z]+$/i, '').downcase + rescue # rescue (anything) from the malformed (or missing) accept language headers + country_to_language(request.host.split('.').last) + end end end diff --git a/lib/locale_detector/version.rb b/lib/locale_detector/version.rb index a1402aa..4fcef97 100644 --- a/lib/locale_detector/version.rb +++ b/lib/locale_detector/version.rb @@ -1,3 +1,3 @@ module LocaleDetector - VERSION = "0.2.0" + VERSION = "0.3.0" end diff --git a/spec/locale_detector/filter_spec.rb b/spec/locale_detector/filter_spec.rb index 90e787a..3a0be31 100644 --- a/spec/locale_detector/filter_spec.rb +++ b/spec/locale_detector/filter_spec.rb @@ -5,21 +5,36 @@ def set_locale(opts = {}) filter = Object.new.extend(LocaleDetector::Filter) - request = if opts[:language].present? + request = + if opts[:language].present? double('request', :env => { 'HTTP_ACCEPT_LANGUAGE' => opts[:language] }) - else + elsif opts[:host].present? double('request', :env => nil, :host => opts[:host]) end + session = + if opts[:session_language].present? + double('session', :[] => opts[:session_language]) + else + double('session', :[] => '') + end + + filter.stub(:session).and_return(session) filter.stub(:request).and_return(request) filter.send(:set_locale) end + context "session[:language] locale overwrite" do + specify { set_locale(:language => 'pt-BR', :session_language => 'pl').should eql('pl') } + end + context "http header locale setting" do specify { set_locale(:language => 'pl').should eql('pl') } specify { set_locale(:language => 'pl-PL').should eql('pl') } + specify { set_locale(:language => 'pt-BR').should eql('pt') } + specify { set_locale(:language => 'pl,en-us;q=0.7,en;q=0.3').should eql('pl') } specify { set_locale(:language => 'lt,en-us;q=0.8,en;q=0.6,ru;q=0.4,pl;q=0.2').should eql('lt') }