rf-web/vendor/bundle/gems/i18n-1.7.0/lib/i18n/backend/chain.rb

132 lines
4.2 KiB
Ruby
Raw Normal View History

2019-10-21 08:18:17 +00:00
# frozen_string_literal: true
module I18n
module Backend
# Backend that chains multiple other backends and checks each of them when
# a translation needs to be looked up. This is useful when you want to use
# standard translations with a Simple backend but store custom application
# translations in a database or other backends.
#
# To use the Chain backend instantiate it and set it to the I18n module.
# You can add chained backends through the initializer or backends
# accessor:
#
# # preserves the existing Simple backend set to I18n.backend
# I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend)
#
# The implementation assumes that all backends added to the Chain implement
# a lookup method with the same API as Simple backend does.
class Chain
using I18n::HashRefinements
module Implementation
include Base
attr_accessor :backends
def initialize(*backends)
self.backends = backends
end
def initialized?
backends.all? do |backend|
backend.instance_eval do
return false unless initialized?
end
end
true
end
def reload!
backends.each { |backend| backend.reload! }
end
def eager_load!
backends.each { |backend| backend.eager_load! }
end
def store_translations(locale, data, options = EMPTY_HASH)
backends.first.store_translations(locale, data, options)
end
def available_locales
backends.map { |backend| backend.available_locales }.flatten.uniq
end
def translate(locale, key, default_options = EMPTY_HASH)
namespace = nil
options = default_options.except(:default)
backends.each do |backend|
catch(:exception) do
options = default_options if backend == backends.last
translation = backend.translate(locale, key, options)
if namespace_lookup?(translation, options)
namespace = _deep_merge(translation, namespace || {})
elsif !translation.nil? || (options.key?(:default) && options[:default].nil?)
return translation
end
end
end
return namespace if namespace
throw(:exception, I18n::MissingTranslation.new(locale, key, options))
end
def exists?(locale, key)
backends.any? do |backend|
backend.exists?(locale, key)
end
end
def localize(locale, object, format = :default, options = EMPTY_HASH)
backends.each do |backend|
catch(:exception) do
result = backend.localize(locale, object, format, options) and return result
end
end
throw(:exception, I18n::MissingTranslation.new(locale, format, options))
end
protected
def init_translations
backends.each do |backend|
backend.send(:init_translations)
end
end
def translations
backends.reverse.each_with_object({}) do |backend, memo|
partial_translations = backend.instance_eval do
init_translations unless initialized?
translations
end
memo.deep_merge!(partial_translations)
end
end
def namespace_lookup?(result, options)
result.is_a?(Hash) && !options.has_key?(:count)
end
private
# This is approximately what gets used in ActiveSupport.
# However since we are not guaranteed to run in an ActiveSupport context
# it is wise to have our own copy. We underscore it
# to not pollute the namespace of the including class.
def _deep_merge(hash, other_hash)
copy = hash.dup
other_hash.each_pair do |k,v|
value_from_other = hash[k]
copy[k] = value_from_other.is_a?(Hash) && v.is_a?(Hash) ? _deep_merge(value_from_other, v) : v
end
copy
end
end
include Implementation
end
end
end