2019-05-02 18:17:27 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2013-05-30 01:53:40 -04:00
|
|
|
module JsLocaleHelper
|
2017-08-09 13:57:58 -04:00
|
|
|
def self.plugin_client_files(locale_str)
|
2021-04-15 21:12:34 -04:00
|
|
|
files = Dir["#{Rails.root}/plugins/*/config/locales/client*.#{locale_str}.yml"]
|
|
|
|
I18n::Backend::DiscourseI18n.sort_locale_files(files)
|
2017-08-09 13:57:58 -04:00
|
|
|
end
|
|
|
|
|
2019-10-26 05:55:54 -04:00
|
|
|
def self.reloadable_plugins(locale_sym, ctx)
|
2017-08-09 13:57:58 -04:00
|
|
|
return unless Rails.env.development?
|
2019-10-26 05:55:54 -04:00
|
|
|
I18n.fallbacks[locale_sym].each do |locale|
|
|
|
|
plugin_client_files(locale.to_s).each { |file| ctx.depend_on(file) }
|
2017-08-09 13:57:58 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-09-28 16:26:36 -04:00
|
|
|
def self.plugin_translations(locale_str)
|
|
|
|
@plugin_translations ||= HashWithIndifferentAccess.new
|
|
|
|
|
|
|
|
@plugin_translations[locale_str] ||= begin
|
|
|
|
translations = {}
|
|
|
|
|
2017-08-09 13:57:58 -04:00
|
|
|
plugin_client_files(locale_str).each do |file|
|
2017-02-24 05:31:21 -05:00
|
|
|
if plugin_translations = YAML.load_file(file)[locale_str]
|
2016-09-30 03:01:42 -04:00
|
|
|
translations.deep_merge!(plugin_translations)
|
|
|
|
end
|
2016-09-28 16:26:36 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
translations
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-15 16:55:31 -05:00
|
|
|
def self.load_translations(locale)
|
2015-07-15 17:23:41 -04:00
|
|
|
@loaded_translations ||= HashWithIndifferentAccess.new
|
2015-07-15 11:56:46 -04:00
|
|
|
@loaded_translations[locale] ||= begin
|
|
|
|
locale_str = locale.to_s
|
|
|
|
|
|
|
|
# load default translations
|
2017-11-16 16:21:53 -05:00
|
|
|
yml_file = "#{Rails.root}/config/locales/client.#{locale_str}.yml"
|
|
|
|
if File.exist?(yml_file)
|
|
|
|
translations = YAML.load_file(yml_file)
|
|
|
|
else
|
|
|
|
# If we can't find a base file in Discourse, it might only exist in a plugin
|
|
|
|
# so let's start with a basic object we can merge into
|
|
|
|
translations = { locale_str => { "js" => {}, "admin_js" => {}, "wizard_js" => {} } }
|
|
|
|
end
|
2015-07-15 11:56:46 -04:00
|
|
|
|
|
|
|
# merge translations (plugin translations overwrite default translations)
|
2017-11-24 14:11:01 -05:00
|
|
|
if translations[locale_str] && plugin_translations(locale_str)
|
2018-06-12 10:09:40 -04:00
|
|
|
translations[locale_str]["js"] ||= {}
|
|
|
|
translations[locale_str]["admin_js"] ||= {}
|
|
|
|
translations[locale_str]["wizard_js"] ||= {}
|
|
|
|
|
2017-11-24 14:11:01 -05:00
|
|
|
if plugin_translations(locale_str)["js"]
|
|
|
|
translations[locale_str]["js"].deep_merge!(plugin_translations(locale_str)["js"])
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
2017-11-24 14:11:01 -05:00
|
|
|
if plugin_translations(locale_str)["admin_js"]
|
|
|
|
translations[locale_str]["admin_js"].deep_merge!(
|
|
|
|
plugin_translations(locale_str)["admin_js"],
|
|
|
|
)
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
2018-04-05 02:52:17 -04:00
|
|
|
if plugin_translations(locale_str)["wizard_js"]
|
|
|
|
translations[locale_str]["wizard_js"].deep_merge!(
|
|
|
|
plugin_translations(locale_str)["wizard_js"],
|
|
|
|
)
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
2017-11-24 14:11:01 -05:00
|
|
|
end
|
2015-07-15 11:56:46 -04:00
|
|
|
|
|
|
|
translations
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-02-24 05:31:21 -05:00
|
|
|
# deeply removes keys from "deleting_from" that are already present in "checking_hashes"
|
|
|
|
def self.deep_delete_matches(deleting_from, checking_hashes)
|
2015-07-15 11:56:46 -04:00
|
|
|
checking_hashes.compact!
|
|
|
|
|
|
|
|
new_hash = deleting_from.dup
|
|
|
|
deleting_from.each do |key, value|
|
2017-02-24 05:31:21 -05:00
|
|
|
if value.is_a?(Hash)
|
|
|
|
new_at_key = deep_delete_matches(deleting_from[key], checking_hashes.map { |h| h[key] })
|
2015-07-15 11:56:46 -04:00
|
|
|
if new_at_key.empty?
|
2017-02-24 05:31:21 -05:00
|
|
|
new_hash.delete(key)
|
2015-07-15 11:56:46 -04:00
|
|
|
else
|
|
|
|
new_hash[key] = new_at_key
|
|
|
|
end
|
|
|
|
else
|
2017-02-24 05:31:21 -05:00
|
|
|
new_hash.delete(key) if checking_hashes.any? { |h| h.include?(key) }
|
2015-07-15 11:56:46 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
new_hash
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.load_translations_merged(*locales)
|
2019-03-07 12:51:12 -05:00
|
|
|
locales = locales.uniq.compact
|
2015-07-15 11:56:46 -04:00
|
|
|
@loaded_merges ||= {}
|
|
|
|
@loaded_merges[locales.join("-")] ||= begin
|
2015-07-15 17:30:16 -04:00
|
|
|
all_translations = {}
|
2015-07-15 11:56:46 -04:00
|
|
|
merged_translations = {}
|
2015-07-15 17:30:16 -04:00
|
|
|
loaded_locales = []
|
|
|
|
|
|
|
|
locales
|
|
|
|
.map(&:to_s)
|
|
|
|
.each do |locale|
|
2017-02-24 05:31:21 -05:00
|
|
|
all_translations[locale] = load_translations(locale)
|
|
|
|
merged_translations[locale] = deep_delete_matches(
|
|
|
|
all_translations[locale][locale],
|
|
|
|
loaded_locales.map { |l| merged_translations[l] },
|
|
|
|
)
|
2015-07-15 17:30:16 -04:00
|
|
|
loaded_locales << locale
|
2015-07-15 11:56:46 -04:00
|
|
|
end
|
|
|
|
merged_translations
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-05-23 15:23:31 -04:00
|
|
|
def self.clear_cache!
|
|
|
|
@loaded_translations = nil
|
|
|
|
@plugin_translations = nil
|
|
|
|
@loaded_merges = nil
|
|
|
|
end
|
|
|
|
|
2016-08-25 16:33:29 -04:00
|
|
|
def self.translations_for(locale_str)
|
2019-05-23 15:23:31 -04:00
|
|
|
clear_cache! if Rails.env.development?
|
2019-01-15 16:55:31 -05:00
|
|
|
|
2019-05-10 19:38:58 -04:00
|
|
|
locale_sym = locale_str.to_sym
|
|
|
|
|
2019-05-23 15:23:31 -04:00
|
|
|
translations =
|
|
|
|
I18n.with_locale(locale_sym) do
|
2018-12-17 18:18:00 -05:00
|
|
|
if locale_sym == :en
|
2016-09-28 16:26:36 -04:00
|
|
|
load_translations(locale_sym)
|
2015-07-15 17:25:24 -04:00
|
|
|
else
|
2019-05-10 19:38:58 -04:00
|
|
|
load_translations_merged(*I18n.fallbacks[locale_sym])
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
2015-07-15 17:25:24 -04:00
|
|
|
end
|
2019-05-23 15:23:31 -04:00
|
|
|
|
|
|
|
Marshal.load(Marshal.dump(translations))
|
2016-08-25 16:33:29 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.output_locale(locale)
|
|
|
|
locale_str = locale.to_s
|
2018-01-25 06:09:18 -05:00
|
|
|
fallback_locale_str = LocaleSiteSetting.fallback_locale(locale_str)&.to_s
|
2019-05-23 15:23:31 -04:00
|
|
|
translations = translations_for(locale_str)
|
2016-08-25 16:33:29 -04:00
|
|
|
|
2019-05-15 17:43:00 -04:00
|
|
|
message_formats = remove_message_formats!(translations, locale)
|
2019-02-19 08:42:58 -05:00
|
|
|
mf_locale, mf_filename = find_message_format_locale([locale_str], fallback_to_english: true)
|
2018-01-25 06:09:18 -05:00
|
|
|
result = generate_message_format(message_formats, mf_locale, mf_filename)
|
2017-03-24 15:42:23 -04:00
|
|
|
|
2018-01-08 18:23:49 -05:00
|
|
|
translations.keys.each do |l|
|
|
|
|
translations[l].keys.each { |k| translations[l].delete(k) unless k == "js" }
|
2016-08-25 16:33:29 -04:00
|
|
|
end
|
|
|
|
|
2017-02-24 05:31:21 -05:00
|
|
|
# I18n
|
2013-05-30 01:53:40 -04:00
|
|
|
result << "I18n.translations = #{translations.to_json};\n"
|
2013-06-11 03:25:50 -04:00
|
|
|
result << "I18n.locale = '#{locale_str}';\n"
|
2018-01-25 06:09:18 -05:00
|
|
|
if fallback_locale_str && fallback_locale_str != "en"
|
|
|
|
result << "I18n.fallbackLocale = '#{fallback_locale_str}';\n"
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
2018-01-25 06:09:18 -05:00
|
|
|
if mf_locale != "en"
|
|
|
|
result << "I18n.pluralizationRules.#{locale_str} = MessageFormat.locale.#{mf_locale};\n"
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
2017-02-24 05:31:21 -05:00
|
|
|
|
|
|
|
# moment
|
2019-02-12 13:57:52 -05:00
|
|
|
result << File.read("#{Rails.root}/vendor/assets/javascripts/moment.js")
|
|
|
|
result << File.read("#{Rails.root}/vendor/assets/javascripts/moment-timezone-with-data.js")
|
2013-06-07 04:03:09 -04:00
|
|
|
result << moment_locale(locale_str)
|
2019-02-25 14:40:02 -05:00
|
|
|
result << moment_locale(locale_str, timezone_names: true)
|
2013-06-11 03:25:50 -04:00
|
|
|
result << moment_formats
|
2014-08-07 12:08:15 -04:00
|
|
|
|
2013-05-30 01:53:40 -04:00
|
|
|
result
|
|
|
|
end
|
|
|
|
|
2021-12-16 15:53:50 -05:00
|
|
|
def self.output_client_overrides(main_locale)
|
|
|
|
all_overrides = {}
|
|
|
|
has_overrides = false
|
2019-11-04 20:15:44 -05:00
|
|
|
|
2021-12-16 15:53:50 -05:00
|
|
|
I18n.fallbacks[main_locale].each do |locale|
|
|
|
|
overrides =
|
|
|
|
all_overrides[locale] = TranslationOverride
|
|
|
|
.where(locale: locale)
|
|
|
|
.where("translation_key LIKE 'js.%' OR translation_key LIKE 'admin_js.%'")
|
|
|
|
.pluck(:translation_key, :value, :compiled_js)
|
2019-11-04 20:15:44 -05:00
|
|
|
|
2021-12-16 15:53:50 -05:00
|
|
|
has_overrides ||= overrides.present?
|
|
|
|
end
|
|
|
|
|
|
|
|
return "" if !has_overrides
|
|
|
|
|
|
|
|
result = +"I18n._overrides = {};"
|
|
|
|
existing_keys = Set.new
|
2021-12-16 10:54:45 -05:00
|
|
|
message_formats = []
|
|
|
|
|
2021-12-16 15:53:50 -05:00
|
|
|
all_overrides.each do |locale, overrides|
|
|
|
|
translations = {}
|
|
|
|
|
|
|
|
overrides.each do |key, value, compiled_js|
|
|
|
|
next if existing_keys.include?(key)
|
|
|
|
existing_keys << key
|
|
|
|
|
|
|
|
if key.end_with?("_MF")
|
|
|
|
message_formats << "#{key.inspect}: #{compiled_js}"
|
|
|
|
else
|
|
|
|
translations[key] = value
|
|
|
|
end
|
2019-11-04 20:15:44 -05:00
|
|
|
end
|
|
|
|
|
2021-12-16 15:53:50 -05:00
|
|
|
result << "I18n._overrides['#{locale}'] = #{translations.to_json};" if translations.present?
|
|
|
|
end
|
2019-11-04 20:15:44 -05:00
|
|
|
|
2021-12-16 15:53:50 -05:00
|
|
|
result << "I18n._mfOverrides = {#{message_formats.join(", ")}};"
|
|
|
|
result
|
2019-11-04 20:15:44 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.output_extra_locales(bundle, locale)
|
|
|
|
translations = translations_for(locale)
|
2022-06-17 13:34:08 -04:00
|
|
|
locales = translations.keys
|
2019-11-04 20:15:44 -05:00
|
|
|
|
2022-06-17 13:34:08 -04:00
|
|
|
locales.each do |l|
|
2019-11-04 20:15:44 -05:00
|
|
|
translations[l].keys.each do |k|
|
|
|
|
bundle_translations = translations[l].delete(k)
|
|
|
|
translations[l].deep_merge!(bundle_translations) if k == bundle
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-06-17 08:50:21 -04:00
|
|
|
return "" if translations.blank?
|
|
|
|
|
2022-06-17 13:34:08 -04:00
|
|
|
output = +"if (!I18n.extras) { I18n.extras = {}; }"
|
|
|
|
locales.each { |l| output << <<~JS }
|
|
|
|
if (!I18n.extras["#{l}"]) { I18n.extras["#{l}"] = {}; }
|
|
|
|
Object.assign(I18n.extras["#{l}"], #{translations[l].to_json});
|
|
|
|
JS
|
2022-06-17 08:50:21 -04:00
|
|
|
|
2022-06-17 13:34:08 -04:00
|
|
|
output
|
2019-11-04 20:15:44 -05:00
|
|
|
end
|
|
|
|
|
2019-04-16 05:41:14 -04:00
|
|
|
MOMENT_LOCALE_MAPPING ||= { "hy" => "hy-am" }
|
2019-03-28 09:47:37 -04:00
|
|
|
|
2019-02-25 14:40:02 -05:00
|
|
|
def self.find_moment_locale(locale_chain, timezone_names: false)
|
|
|
|
if timezone_names
|
|
|
|
path = "#{Rails.root}/vendor/assets/javascripts/moment-timezone-names-locale"
|
|
|
|
type = :moment_js_timezones
|
|
|
|
else
|
|
|
|
path = "#{Rails.root}/vendor/assets/javascripts/moment-locale"
|
|
|
|
type = :moment_js
|
|
|
|
end
|
2018-01-25 06:09:18 -05:00
|
|
|
|
2019-02-25 14:40:02 -05:00
|
|
|
find_locale(locale_chain, path, type, fallback_to_english: false) do |locale|
|
2019-03-28 09:47:37 -04:00
|
|
|
locale = MOMENT_LOCALE_MAPPING[locale] if MOMENT_LOCALE_MAPPING.key?(locale)
|
2019-02-19 09:27:30 -05:00
|
|
|
# moment.js uses a different naming scheme for locale files
|
2019-02-19 10:07:19 -05:00
|
|
|
locale.tr("_", "-").downcase
|
2019-02-19 09:27:30 -05:00
|
|
|
end
|
2018-01-25 06:09:18 -05:00
|
|
|
end
|
|
|
|
|
2019-02-19 08:42:58 -05:00
|
|
|
def self.find_message_format_locale(locale_chain, fallback_to_english:)
|
2018-01-25 06:09:18 -05:00
|
|
|
path = "#{Rails.root}/lib/javascripts/locale"
|
2019-02-19 08:42:58 -05:00
|
|
|
find_locale(locale_chain, path, :message_format, fallback_to_english: fallback_to_english)
|
2018-01-25 06:09:18 -05:00
|
|
|
end
|
|
|
|
|
2019-02-19 08:42:58 -05:00
|
|
|
def self.find_locale(locale_chain, path, type, fallback_to_english:)
|
2019-08-26 10:17:56 -04:00
|
|
|
locale_chain.map!(&:to_s)
|
|
|
|
|
2018-01-25 06:09:18 -05:00
|
|
|
locale_chain.each do |locale|
|
|
|
|
plugin_locale = DiscoursePluginRegistry.locales[locale]
|
|
|
|
return plugin_locale[type] if plugin_locale&.has_key?(type)
|
|
|
|
|
2019-02-19 10:07:19 -05:00
|
|
|
locale = yield(locale) if block_given?
|
2018-01-25 06:09:18 -05:00
|
|
|
filename = File.join(path, "#{locale}.js")
|
|
|
|
return locale, filename if File.exist?(filename)
|
|
|
|
end
|
|
|
|
|
2019-02-19 10:07:19 -05:00
|
|
|
locale_chain.map! { |locale| yield(locale) } if block_given?
|
2019-02-19 09:27:30 -05:00
|
|
|
|
2018-01-25 06:09:18 -05:00
|
|
|
# try again, but this time only with the language itself
|
|
|
|
locale_chain =
|
|
|
|
locale_chain.map { |l| l.split(/[-_]/)[0] }.uniq.reject { |l| locale_chain.include?(l) }
|
2019-02-19 10:07:19 -05:00
|
|
|
|
|
|
|
if locale_chain.any?
|
2019-02-19 08:42:58 -05:00
|
|
|
locale_data = find_locale(locale_chain, path, type, fallback_to_english: false)
|
2018-01-25 06:09:18 -05:00
|
|
|
return locale_data if locale_data
|
|
|
|
end
|
|
|
|
|
2021-05-20 21:43:47 -04:00
|
|
|
# English should always work
|
2018-01-25 06:09:18 -05:00
|
|
|
["en", File.join(path, "en.js")] if fallback_to_english
|
|
|
|
end
|
|
|
|
|
2013-06-11 03:25:50 -04:00
|
|
|
def self.moment_formats
|
2019-05-02 18:17:27 -04:00
|
|
|
result = +""
|
2013-06-11 03:25:50 -04:00
|
|
|
result << moment_format_function("short_date_no_year")
|
|
|
|
result << moment_format_function("short_date")
|
|
|
|
result << moment_format_function("long_date")
|
2013-06-12 02:38:02 -04:00
|
|
|
result << "moment.fn.relativeAge = function(opts){ return Discourse.Formatter.relativeAge(this.toDate(), opts)};\n"
|
2013-06-11 03:25:50 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.moment_format_function(name)
|
2014-03-26 10:55:40 -04:00
|
|
|
format = I18n.t("dates.#{name}")
|
2015-08-20 12:03:43 -04:00
|
|
|
"moment.fn.#{name.camelize(:lower)} = function(){ return this.format('#{format}'); };\n"
|
2013-06-11 03:25:50 -04:00
|
|
|
end
|
|
|
|
|
2019-02-25 14:40:02 -05:00
|
|
|
def self.moment_locale(locale, timezone_names: false)
|
|
|
|
_, filename = find_moment_locale([locale], timezone_names: timezone_names)
|
2018-01-25 06:09:18 -05:00
|
|
|
filename && File.exist?(filename) ? File.read(filename) << "\n" : ""
|
2013-06-07 04:03:09 -04:00
|
|
|
end
|
|
|
|
|
2018-01-25 06:09:18 -05:00
|
|
|
def self.generate_message_format(message_formats, locale, filename)
|
|
|
|
formats =
|
|
|
|
message_formats
|
|
|
|
.map { |k, v| k.inspect << " : " << compile_message_format(filename, locale, v) }
|
|
|
|
.join(", ")
|
2016-04-08 14:49:50 -04:00
|
|
|
|
2019-05-02 18:17:27 -04:00
|
|
|
result = +"MessageFormat = {locale: {}};\n"
|
2017-02-24 05:31:21 -05:00
|
|
|
result << "I18n._compiledMFs = {#{formats}};\n"
|
|
|
|
result << File.read(filename) << "\n"
|
2022-02-07 20:31:08 -05:00
|
|
|
|
|
|
|
if locale != "en"
|
|
|
|
# Include "en" pluralization rules for use in fallbacks
|
|
|
|
_, en_filename = find_message_format_locale(["en"], fallback_to_english: false)
|
|
|
|
result << File.read(en_filename) << "\n"
|
|
|
|
end
|
|
|
|
|
2017-02-24 05:31:21 -05:00
|
|
|
result << File.read("#{Rails.root}/lib/javascripts/messageformat-lookup.js") << "\n"
|
2013-05-30 01:53:40 -04:00
|
|
|
end
|
|
|
|
|
2016-11-01 22:34:20 -04:00
|
|
|
def self.reset_context
|
2017-07-20 00:17:45 -04:00
|
|
|
@ctx&.dispose
|
2016-11-01 22:34:20 -04:00
|
|
|
@ctx = nil
|
|
|
|
end
|
|
|
|
|
2016-05-19 08:25:08 -04:00
|
|
|
@mutex = Mutex.new
|
|
|
|
def self.with_context
|
|
|
|
@mutex.synchronize do
|
|
|
|
yield(
|
|
|
|
@ctx ||=
|
|
|
|
begin
|
2020-05-15 00:01:54 -04:00
|
|
|
ctx = MiniRacer::Context.new(timeout: 15_000, ensure_gc_after_idle: 2000)
|
2018-06-10 20:40:05 -04:00
|
|
|
ctx.load("#{Rails.root}/lib/javascripts/messageformat.js")
|
|
|
|
ctx
|
|
|
|
end
|
2023-01-09 07:10:19 -05:00
|
|
|
)
|
2016-05-19 08:25:08 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-01-25 06:09:18 -05:00
|
|
|
def self.compile_message_format(path, locale, format)
|
2016-05-19 08:25:08 -04:00
|
|
|
with_context do |ctx|
|
2018-01-25 06:09:18 -05:00
|
|
|
ctx.load(path) if File.exist?(path)
|
2016-05-19 08:25:08 -04:00
|
|
|
ctx.eval("mf = new MessageFormat('#{locale}');")
|
|
|
|
ctx.eval("mf.precompile(mf.parse(#{format.inspect}))")
|
|
|
|
end
|
|
|
|
rescue MiniRacer::EvalError => e
|
2019-05-02 18:17:27 -04:00
|
|
|
message = +"Invalid Format: " << e.message
|
2013-05-30 01:53:40 -04:00
|
|
|
"function(){ return #{message.inspect};}"
|
|
|
|
end
|
|
|
|
|
2019-05-15 17:43:00 -04:00
|
|
|
def self.remove_message_formats!(translations, locale)
|
|
|
|
message_formats = {}
|
|
|
|
I18n.fallbacks[locale]
|
|
|
|
.map(&:to_s)
|
|
|
|
.each do |l|
|
|
|
|
next unless translations.key?(l)
|
|
|
|
|
|
|
|
%w[js admin_js].each do |k|
|
|
|
|
message_formats.merge!(strip_out_message_formats!(translations[l][k]))
|
2023-01-09 07:10:19 -05:00
|
|
|
end
|
2019-05-15 17:43:00 -04:00
|
|
|
end
|
|
|
|
message_formats
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.strip_out_message_formats!(hash, prefix = "", message_formats = {})
|
2014-03-26 15:20:41 -04:00
|
|
|
if hash.is_a?(Hash)
|
|
|
|
hash.each do |key, value|
|
|
|
|
if value.is_a?(Hash)
|
2019-05-15 17:43:00 -04:00
|
|
|
message_formats.merge!(
|
|
|
|
strip_out_message_formats!(value, join_key(prefix, key), message_formats),
|
|
|
|
)
|
2014-03-26 15:20:41 -04:00
|
|
|
elsif key.to_s.end_with?("_MF")
|
2019-05-15 17:43:00 -04:00
|
|
|
message_formats[join_key(prefix, key)] = value
|
2014-03-26 15:20:41 -04:00
|
|
|
hash.delete(key)
|
2013-05-30 01:53:40 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-05-15 17:43:00 -04:00
|
|
|
message_formats
|
2013-05-30 01:53:40 -04:00
|
|
|
end
|
|
|
|
|
2019-05-15 17:43:00 -04:00
|
|
|
def self.join_key(prefix, key)
|
|
|
|
prefix.blank? ? key : "#{prefix}.#{key}"
|
|
|
|
end
|
2013-05-30 01:53:40 -04:00
|
|
|
end
|