Skip to content

Commit 395b945

Browse files
authored
Merge pull request #1058 from rughh/feat/detect_browser_locale
feat: detect browser locale
2 parents a4a89a1 + eda92b4 commit 395b945

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

app/controllers/concerns/locale_detection.rb

+20-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module LocaleDetection
44
protected
55

66
def switch_locale
7-
locale = params[:locale] || cookies[:locale]
7+
locale = params[:locale] || cookies[:locale] || available_accepted_locales
88
I18n.locale = allowed_locale?(locale) ? locale : default_locale
99

1010
cookies[:locale] = {
@@ -21,4 +21,23 @@ def allowed_locale?(locale)
2121
def default_locale
2222
Whitelabel.label ? Whitelabel[:default_locale] : I18n.default_locale
2323
end
24+
25+
def available_accepted_locales
26+
(accepted_locales & I18n.available_locales).first
27+
end
28+
29+
def accepted_locales
30+
locales = parsed_accepted_locales.sort_by(&:last).reverse
31+
locales.map(&:first)
32+
end
33+
34+
def parsed_accepted_locales
35+
accepted_locales = request.env['HTTP_ACCEPT_LANGUAGE']&.split(',')
36+
return [] unless accepted_locales
37+
38+
accepted_locales.map do |prefered_locale|
39+
locale, quality = prefered_locale.strip.split(/;(?:q=)/)
40+
[locale.strip.to_sym, quality&.to_f || 1.0]
41+
end
42+
end
2443
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe LocaleDetection do
6+
controller(ApplicationController) do
7+
def index
8+
head :ok
9+
end
10+
end
11+
12+
before do
13+
routes.draw { get 'index' => 'anonymous#index' }
14+
end
15+
16+
it 'concern is included' do
17+
expect(controller.class.ancestors.include?(described_class)).to be(true)
18+
end
19+
20+
it 'uses the default locale if no locale is requested and browser doesnt provide locales' do
21+
get :index
22+
expect(I18n.locale).to eq(I18n.default_locale)
23+
end
24+
25+
it 'uses the defaut locale if the browser provided ones arent available' do
26+
request.headers.merge! 'Accept-Language': 'fr-CH, fr;q=0.9, *;q=0.5'
27+
get :index
28+
expect(I18n.locale).to eq(I18n.default_locale)
29+
end
30+
31+
it 'uses the default locale if the requested locale is not available' do
32+
get :index, params: { locale: 'yy' }
33+
expect(I18n.locale).to eq(I18n.default_locale)
34+
end
35+
36+
it 'uses first matching locale from browser provided list' do
37+
request.headers.merge! 'Accept-Language': 'pl-PL, pl;q=0.9, en;q=0.8, *;q=0.5'
38+
get :index
39+
expect(I18n.locale).to eq(:pl)
40+
end
41+
42+
it 'switches the locale via params' do
43+
get :index, params: { locale: 'de' }
44+
expect(I18n.locale).to eq(:de)
45+
expect(cookies[:locale]).to eq('de')
46+
end
47+
48+
it 'uses the locale from a cookie' do
49+
cookies[:locale] = 'pl'
50+
get :index
51+
expect(I18n.locale).to eq(:pl)
52+
end
53+
end

0 commit comments

Comments
 (0)