FIX: Correctly calculate fallback locale list

FIX: Correctly calculate fallback locale list

  • English shouldn’t fallback to any other locale
  • Calculate fallback for default locale if it isn’t English (useful for en_US)
  • Reuse the fallback locale list when outputting translations to JavaScript
diff --git a/lib/i18n/backend/fallback_locale_list.rb b/lib/i18n/backend/fallback_locale_list.rb
index 600e86b..d0abe59 100644
--- a/lib/i18n/backend/fallback_locale_list.rb
+++ b/lib/i18n/backend/fallback_locale_list.rb
@@ -5,8 +5,21 @@ module I18n
     # Configure custom fallback order
     class FallbackLocaleList < Hash
       def [](locale)
+        locale = locale.to_sym
+        return [locale] if locale == :en
+
         fallback_locale = LocaleSiteSetting.fallback_locale(locale)
-        [locale, fallback_locale, SiteSetting.default_locale.to_sym, :en].uniq.compact
+        site_locale = SiteSetting.default_locale.to_sym
+
+        locale_list =
+          if locale == site_locale || site_locale == :en
+            [locale, fallback_locale, :en]
+          else
+            site_fallback_locale = LocaleSiteSetting.fallback_locale(site_locale)
+            [locale, fallback_locale, site_locale, site_fallback_locale, :en]
+          end
+
+        locale_list.uniq.compact
       end
     end
   end
diff --git a/lib/js_locale_helper.rb b/lib/js_locale_helper.rb
index 2a602a1..71b0eec 100644
--- a/lib/js_locale_helper.rb
+++ b/lib/js_locale_helper.rb
@@ -105,31 +105,21 @@ module JsLocaleHelper
   end
 
   def self.translations_for(locale_str)
-    current_locale  = I18n.locale
-    locale_sym      = locale_str.to_sym
-    site_locale     = SiteSetting.default_locale.to_sym
-    fallback_locale = LocaleSiteSetting.fallback_locale(locale_str)
-
-    I18n.locale = locale_sym
-
     if Rails.env.development?
       @loaded_translations = nil
       @plugin_translations = nil
       @loaded_merges = nil
     end
 
-    translations =
+    locale_sym = locale_str.to_sym
+
+    I18n.with_locale(locale_sym) do
       if locale_sym == :en
         load_translations(locale_sym)
-      elsif locale_sym == site_locale || site_locale == :en
-        load_translations_merged(locale_sym, fallback_locale, :en)
       else
-        load_translations_merged(locale_sym, fallback_locale, site_locale, :en)
+        load_translations_merged(*I18n.fallbacks[locale_sym])
       end
-
-    I18n.locale = current_locale
-
-    translations
+    end
   end
 
   def self.output_locale(locale)
diff --git a/spec/components/fallback_locale_list_spec.rb b/spec/components/fallback_locale_list_spec.rb
index d6cc02f..718dd8f 100644
--- a/spec/components/fallback_locale_list_spec.rb
+++ b/spec/components/fallback_locale_list_spec.rb
@@ -18,7 +18,7 @@ describe I18n::Backend::FallbackLocaleList do
 
     expect(list[:ru]).to eq([:ru, :de, :en])
     expect(list[:de]).to eq([:de, :en])
-    expect(list[:en]).to eq([:en, :de])
+    expect(list[:en]).to eq([:en])
   end
 
   context "when plugin registered fallback locale" do
@@ -44,7 +44,7 @@ describe I18n::Backend::FallbackLocaleList do
 
       expect(list[:es_MX]).to eq([:es_MX, :es, :de, :en])
       expect(list[:es]).to eq([:es, :de, :en])
-      expect(list[:en]).to eq([:en, :de])
+      expect(list[:en]).to eq([:en])
     end
   end
 end

GitHub sha: 73015521

1 Like