Last active
December 21, 2015 06:18
-
-
Save ichiban/6262977 to your computer and use it in GitHub Desktop.
Set I18N locale based on HTTP_ACCEPT_LANGUAGE header.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ApplicationController < ActionController::Base | |
# ... | |
before_filter :set_locale | |
# ... | |
def set_locale | |
logger.debug "* Accept-Language: #{request.env['HTTP_ACCEPT_LANGUAGE']}" | |
I18n.locale = locale_string(locale) if locale | |
logger.debug "* Locale set to '#{I18n.locale}'" | |
end | |
private | |
def locale | |
@local ||= locale_from_param || locale_from_header | |
end | |
def locale_hash(local_string) | |
locale, qvalue = local_string.split(';q=') | |
language, territory = locale.split('-') | |
{ | |
language: language.downcase, | |
territory: territory ? territory.upcase : nil, | |
qvalue: qvalue ? qvalue.to_f : 1.0 | |
} | |
end | |
def locale_string(locale_hash) | |
language = locale_hash[:language].downcase | |
territory = locale_hash[:territory].upcase if locale_hash[:territory] | |
territory ? "#{language}-#{territory}" : language | |
end | |
# convert a locale hash into an available locale hash. | |
# if this app supports the given locale, returns the locale. | |
# if this app supports not the exact locale but an alternate locale with the same language, | |
# returns the alternate locale. | |
# otherwise, returns nil. | |
def available_locale(locale) | |
@@available_locales ||= ['en', 'ja'].map{|l| locale_hash(l) } | |
same_languages = @@available_locales.select{|l| l[:language] == locale[:language] } | |
exact_sames = same_languages.select{|l| l[:territory] == locale[:territory] } | |
exact_sames.empty? ? same_languages.first : exact_sames.first | |
end | |
def locale_from_param | |
return nil unless params[:locale] | |
locale = locale_hash(params[:locale]) | |
available_locale(locale) | |
end | |
def locale_from_header | |
http_accept_language = request.env['HTTP_ACCEPT_LANGUAGE'] | |
return nil unless http_accept_language | |
locales = http_accept_language.gsub(/\s+/, '').split(/,/).map{|l| locale_hash(l) } | |
# sort locale hashes by qvalue. to make it descending order, reverse it. | |
sorted_locales = locales.sort{|a, b| a[:qvalue] <=> b[:qvalue] }.reverse! | |
filtered_locales = sorted_locales.map{|l| available_locale(l) } | |
filtered_locales.first | |
rescue => e | |
nil | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment