Created
January 22, 2022 16:32
-
-
Save BroHandTW/b44716106f0e45b875406618ad27b68d to your computer and use it in GitHub Desktop.
This file contains 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
module WebI18nLocale | |
extend ActiveSupport::Concern | |
included do | |
prepend_before_action :digest_locale_params | |
before_action :set_locale | |
helper_method :set_locale_path | |
end | |
private | |
def digest_locale_params | |
return unless params[:locale] && request.get? | |
session[:locale] = resolve_locale(params[:locale]) | |
redirect_to url_for(request.params.except(:locale).merge(only_path: true)) | |
end | |
def set_locale_path(locale) | |
url_for(request.params.merge(locale: locale, only_path: true)) | |
end | |
def set_locale | |
the_locale = session_locale || browser_locale | |
I18n.locale = the_locale | |
@pagy_locale = the_locale.to_s # for pagy i18n | |
end | |
def resolve_locale(str) | |
locale = String(str).to_sym | |
I18n.available_locales.include?(locale) ? locale : nil | |
end | |
def session_locale | |
@session_locale ||= resolve_locale(session[:locale]) | |
end | |
def browser_locale | |
@browser_locale ||= compatible_language_from(I18n.available_locales) | |
end | |
# references http_accept_language gem | |
def user_preferred_languages # rubocop:disable all | |
@user_preferred_languages ||= begin | |
header = request.env['HTTP_ACCEPT_LANGUAGE'] | |
locale_quality_array = header.to_s.gsub(/\s+/, '').split(',').map do |language| | |
locale, quality = language.split(';q=') | |
raise ArgumentError, 'Not correctly formatted' unless locale =~ /^[a-z\-0-9]+|\*$/i | |
locale = locale.downcase.gsub(/-[a-z0-9]+$/i, &:upcase) # Uppercase territory | |
locale = nil if locale == '*' # Ignore wildcards | |
quality = quality ? quality.to_f : 1.0 | |
[locale, quality] | |
end | |
locale_quality_array.sort { |(_, left), (_, right)| right <=> left }.map(&:first).compact | |
rescue ArgumentError # Just rescue anything if the browser messed up badly. | |
[] | |
end | |
end | |
# references http_accept_language gem | |
def compatible_language_from(available_languages) | |
user_preferred_languages.map do |preferred| # en-US | |
preferred = preferred.downcase | |
preferred_language = preferred.split('-', 2).first | |
available_languages.find do |available| # en | |
available = available.to_s.downcase | |
preferred == available || preferred_language == available.split('-', 2).first | |
end | |
end.compact.first | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment