# frozen_string_literal: truemoduleI18nmoduleBackend# This module contains several helpers to assist flattening translations.# You may want to flatten translations for:## 1) speed up lookups, as in the Memoize backend;# 2) In case you want to store translations in a data store, as in ActiveRecord backend;## You can check both backends above for some examples.# This module also keeps all links in a hash so they can be properly resolved when flattened.moduleFlattenSEPARATOR_ESCAPE_CHAR="\001"FLATTEN_SEPARATOR="."# normalize_keys the flatten way. This method is significantly faster# and creates way less objects than the one at I18n.normalize_keys.# It also handles escaping the translation keys.defself.normalize_flat_keys(locale,key,scope,separator)keys=[scope,key]keys.flatten!keys.compact!separator||=I18n.default_separatorifseparator!=FLATTEN_SEPARATORfrom_str="#{FLATTEN_SEPARATOR}#{separator}"to_str="#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}"keys.map!{|k|k.to_s.trfrom_str,to_str}endkeys.join(".")end# Receives a string and escape the default separator.defself.escape_default_separator(key)#:nodoc:key.to_s.tr(FLATTEN_SEPARATOR,SEPARATOR_ESCAPE_CHAR)end# Shortcut to I18n::Backend::Flatten.normalize_flat_keys# and then resolve_links.defnormalize_flat_keys(locale,key,scope,separator)key=I18n::Backend::Flatten.normalize_flat_keys(locale,key,scope,separator)resolve_link(locale,key)end# Store flattened links.deflinks@links||=I18n.new_double_nested_cacheend# Flatten keys for nested Hashes by chaining up keys:## >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind# => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }#defflatten_keys(hash,escape,prev_key=nil,&block)hash.each_pairdo|key,value|key=escape_default_separator(key)ifescapecurr_key=[prev_key,key].compact.join(FLATTEN_SEPARATOR).to_symyieldcurr_key,valueflatten_keys(value,escape,curr_key,&block)ifvalue.is_a?(Hash)endend# Receives a hash of translations (where the key is a locale and# the value is another hash) and return a hash with all# translations flattened.## Nested hashes are included in the flattened hash just if subtree# is true and Symbols are automatically stored as links.defflatten_translations(locale,data,escape,subtree)hash={}flatten_keys(data,escape)do|key,value|ifvalue.is_a?(Hash)hash[key]=valueifsubtreeelsestore_link(locale,key,value)ifvalue.is_a?(Symbol)hash[key]=valueendendhashendprotecteddefstore_link(locale,key,link)links[locale.to_sym][key.to_s]=link.to_senddefresolve_link(locale,key)key,locale=key.to_s,locale.to_symlinks=self.links[locale]iflinks.key?(key)links[key]elsiflink=find_link(locale,key)store_link(locale,key,key.gsub(*link))elsekeyendenddeffind_link(locale,key)#:nodoc:links[locale].each_pairdo|from,to|return[from,to]ifkey[0,from.length]==fromend&&nilenddefescape_default_separator(key)#:nodoc:I18n::Backend::Flatten.escape_default_separator(key)endendendend