FIX: translation precedence was different on client and server

As an example, the lookup order for German was:

1. override for de
2. override for en
3. value from de
4. value from en

After this change the lookup order is the same as on the client:
1. override for de
2. value from de
3. override for en
4. value from en

see /t/16381
This commit is contained in:
Gerhard Schlager
2021-12-16 16:44:21 +01:00
committed by Gerhard Schlager
parent 8e9799da72
commit e19a7a7c8d
4 changed files with 114 additions and 45 deletions

View File

@@ -72,21 +72,33 @@ module I18n
execute_reload if @requires_reload
locale = (opts[:locale] || config.locale).to_sym
load_locale(locale) unless @loaded_locales.include?(locale)
opts ||= {}
target = opts[:backend] || backend
results = opts[:overridden] ? {} : target.search(locale, query)
results = {}
regexp = I18n::Backend::DiscourseI18n.create_search_regexp(query)
(overrides_by_locale(locale) || {}).each do |k, v|
results.delete(k)
results[k] = v if (k =~ regexp || v =~ regexp)
if opts[:only_overridden]
add_if_matches(overrides_by_locale(locale), results, regexp)
else
target = opts[:backend] || backend
I18n.fallbacks[locale].reverse_each do |fallback|
add_if_matches(target.search(fallback, query), results, regexp)
add_if_matches(overrides_by_locale(fallback), results, regexp)
end
end
results
end
def add_if_matches(translations, results, regexp)
translations.each do |key, value|
if key =~ regexp || value =~ regexp
results[key] = value
end
end
end
def ensure_loaded!(locale)
locale = locale.to_sym
@loaded_locales ||= []
@@ -144,7 +156,7 @@ module I18n
end
def overrides_by_locale(locale)
return unless @overrides_enabled
return {} unless @overrides_enabled
return {} if GlobalSetting.skip_db?
locale = locale.to_sym
@@ -191,30 +203,26 @@ module I18n
if @overrides_enabled
overrides = {}
# for now lets do all the expensive work for keys with count
# no choice really
has_override = !!options[:count]
has_count = options.has_key?(:count)
I18n.fallbacks[locale].each do |l|
override = overrides[l] = overrides_by_locale(l)
has_override ||= override.key?(key)
overrides_for_locale = overrides_by_locale(l)
overrides[l] = overrides_for_locale if has_count || overrides_for_locale.key?(key)
end
if has_override && overrides.present?
if options.present?
options[:overrides] = overrides
if overrides.present?
no_options = options.empty? || (options.size == 1 && options.has_key?(:locale))
# I18n likes to use throw...
catch(:exception) do
return backend.translate(locale, key, options)
end
else
overrides.each do |_k, v|
if result = v[key]
return result
end
end
# Shortcut if the current locale has an override and there are no options.
if no_options && (override = overrides.dig(locale, key))
return override
end
options[:overrides] = overrides
# I18n likes to use throw...
catch(:exception) do
return backend.translate(locale, key, options)
end
end
end

View File

@@ -55,14 +55,8 @@ module I18n
end
def search(locale, query)
results = {}
regexp = self.class.create_search_regexp(query)
I18n.fallbacks[locale].each do |fallback|
find_results(regexp, results, translations[fallback])
end
results
find_results(regexp, {}, translations[locale])
end
protected