Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
117 lines (101 sloc) 3.79 KB
unless RUBY_VERSION >= '1.9'
require "yaml/encoding"
end
require "i18n_translation_spawner/string"
require "i18n_translation_spawner/hash"
require "i18n_translation_spawner/lambda_accessor"
module I18n
class TranslationSpawner
include LambdaAccessor
class CannotDecodeTranslationFilePath < StandardError;
end
attr_accessor :skip_locales, :removable_prefixes, :default_translations, :exception_handler,
:translations_handler, :cannot_decode_translation_file_path_handler
private
def initialize
@skip_locales = []
@removable_prefixes = []
@default_translations = {}.with_indifferent_access
end
lambda_accessor :translation_for_key, :file_path_decoder
def translation(key, locale)
if translations_handler.respond_to?(:call)
translations_handler.call(key, locale, self)
else
default_translation(key, locale)
end
end
def spawn_translation_key(key, locale, options, exception)
I18n.available_locales.reject { |l| skip_locales.map(&:to_s).include?(l.to_s) }.each do |_locale|
begin
begin
I18n.translate(key, options.merge({:locale => _locale, :raise => true}))
rescue I18n::MissingTranslationData
file_path_decoder(key, _locale).tap do |path|
translations_hash = YAML::load_file(path)
hash_to_merge = "#{_locale.to_s}.#{key}".to_hash(translation(key, _locale.to_s)).deep_stringify_keys!
translations_hash = translations_hash.deep_merge(hash_to_merge).to_ordered_hash
translation_content = translations_hash.ya2yaml.sub(/---\s*/, '')
File.open(path, 'w') { |f| f.write(RUBY_VERSION >= '1.9' ? translation_content : YAML.unescape(translation_content)) }
end
end
rescue CannotDecodeTranslationFilePath
if cannot_decode_translation_file_path_handler.respond_to?(:call)
cannot_decode_translation_file_path_handler.call(key, locale, options, exception)
else
Rails.logger.info "=== Cannot access translation file for #{key.to_s}"
return(options[:rescue_format] == :html ? exception.html_message : exception.message)
end
end
end
translation(key, locale.to_s)
end
public
def default_file_path_decoder_handler(*args)
key, locale = args
if File.file?(path = File.join(Rails.root, "config/locales", "#{locale.to_s}.yml"))
path
else
raise CannotDecodeTranslationFilePath
end
end
def default_translation(key, locale)
if translations_handler.respond_to?(:call)
translations_handler(key, locale, self)
else
_key = key.to_s.dup
while _key.present?
if (val = default_translations[_key]).present?
if val.is_a?(Hash)
return(val[locale].present? ? val[locale] : translation_for_key(key, locale))
else
return(val.to_s)
end
else
_key.sub!(/([a-zA-Z0-9_]*\.?)/, '')
end
end
translation_for_key(key, locale)
end
end
def default_translation_for_key_handler(*args)
key, locale = args
key.split('.').last.sub(/\A#{removable_prefixes.map { |prefix| prefix+'_' }.join('|')}/, '').humanize
end
def call(exception, locale, key, options)
if exception_handler.respond_to?(:call)
exception_handler.call(exception, locale, key, self, options)
else
handle_exception(exception, locale, key, options)
end
end
def handle_exception(exception, locale, key, options)
case exception
when I18n::MissingTranslationData
spawn_translation_key(key, locale, options, exception)
else
raise exception
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.