From 4028f4cdb91f616bc774dc9b9fa8c7183eb1f6dd Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Wed, 6 Jan 2016 18:43:25 +0000 Subject: [PATCH] Rework locale selection Implement our own matching algorithm rather than trying to patch the http_accept_language one and make sure everything is using it in a consistent way. Fixes #1125 --- app/controllers/amf_controller.rb | 10 +++-- app/controllers/application_controller.rb | 45 +++++++-------------- app/models/notifier.rb | 8 +--- app/models/user.rb | 4 +- app/views/site/_potlatch2.html.erb | 2 +- app/views/site/id.html.erb | 2 +- config/initializers/http_accept_language.rb | 14 ------- config/initializers/i18n.rb | 10 +++++ lib/id.rb | 2 +- lib/locale.rb | 44 ++++++++++++++++++++ test/integration/user_creation_test.rb | 2 +- test/models/user_test.rb | 2 +- 12 files changed, 82 insertions(+), 63 deletions(-) delete mode 100644 config/initializers/http_accept_language.rb create mode 100644 lib/locale.rb diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index f6ae7f231..f2b592b49 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -190,11 +190,13 @@ class AmfController < ApplicationController user = getuser(usertoken) if user && !user.languages.empty? - http_accept_language.user_preferred_languages = user.languages + langs = Locale.list(user.languages) + else + langs = Locale.list(http_accept_language.user_preferred_languages) end - lang = http_accept_language.compatible_language_from(getlocales) - (real_lang, localised) = getlocalized(lang) + lang = getlocales.preferred(langs) + (real_lang, localised) = getlocalized(lang.to_s) # Tell Potlatch what language it's using localised["__potlatch_locale"] = real_lang @@ -874,7 +876,7 @@ class AmfController < ApplicationController end def getlocales - Dir.glob("#{Rails.root}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") } + @locales ||= Locale.list(Dir.glob("#{Rails.root}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") }) end ## diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2ee701e9c..9954b775b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -288,47 +288,30 @@ class ApplicationController < ActionController::Base end end - def set_locale - response.header["Vary"] = "Accept-Language" - - if @user && !@user.languages.empty? - http_accept_language.user_preferred_languages = @user.languages - response.header["Vary"] = "*" - end + def preferred_languages + @languages ||= if params[:locale] + Locale.list(params[:locale]) + elsif @user + @user.preferred_languages + else + Locale.list(http_accept_language.user_preferred_languages) + end + end - I18n.locale = select_locale + helper_method :preferred_languages + def set_locale if @user && @user.languages.empty? && !http_accept_language.user_preferred_languages.empty? @user.languages = http_accept_language.user_preferred_languages @user.save end - response.headers["Content-Language"] = I18n.locale.to_s - end - - def select_locale(locales = I18n.available_locales) - if params[:locale] - http_accept_language.user_preferred_languages = [params[:locale]] - end - - if http_accept_language.compatible_language_from(locales).nil? - http_accept_language.user_preferred_languages = http_accept_language.user_preferred_languages.collect do |pl| - pls = [pl] - - while pl.match(/^(.*)-[^-]+$/) - pls.push($1) if locales.include?($1) || locales.include?($1.to_sym) - pl = $1 - end - - pls - end.flatten - end + I18n.locale = Locale.available.preferred(preferred_languages) - http_accept_language.compatible_language_from(locales) || I18n.default_locale + response.headers["Vary"] = "Accept-Language" + response.headers["Content-Language"] = I18n.locale.to_s end - helper_method :select_locale - def api_call_handle_error yield rescue ActiveRecord::RecordNotFound => ex diff --git a/app/models/notifier.rb b/app/models/notifier.rb index 018226566..a9bc0d101 100644 --- a/app/models/notifier.rb +++ b/app/models/notifier.rb @@ -175,14 +175,8 @@ class Notifier < ActionMailer::Base private def with_recipient_locale(recipient) - old_locale = I18n.locale - - begin - I18n.locale = recipient.preferred_language_from(I18n.available_locales) - + I18n.with_locale Locale.available.preferred(recipient.preferred_languages) do yield - ensure - I18n.locale = old_locale end end diff --git a/app/models/user.rb b/app/models/user.rb index 0053333e2..eae917af8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -131,8 +131,8 @@ class User < ActiveRecord::Base languages.find { |l| Language.exists?(:code => l) } end - def preferred_language_from(array) - (languages & array.collect(&:to_s)).first + def preferred_languages + @locales ||= Locale.list(languages) end def nearby(radius = NEARBY_RADIUS, num = NEARBY_USERS) diff --git a/app/views/site/_potlatch2.html.erb b/app/views/site/_potlatch2.html.erb index 3aeafa9cf..1c203b2fb 100644 --- a/app/views/site/_potlatch2.html.erb +++ b/app/views/site/_potlatch2.html.erb @@ -10,7 +10,7 @@ <% end %> -<% locale = select_locale(Potlatch2::LOCALES.keys).to_s %> +<% locale = Locale.list(Potlatch2::LOCALES.keys).preferred(preferred_languages).to_s %>