i18n_translation_spawner 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/i18n_translation_spawner/hash.rb +40 -0
 - data/lib/i18n_translation_spawner/string.rb +15 -0
 - data/lib/i18n_translation_spawner.rb +111 -0
 - metadata +81 -0
 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Hash
         
     | 
| 
      
 2 
     | 
    
         
            +
              def deep_stringify_keys
         
     | 
| 
      
 3 
     | 
    
         
            +
                inject({}) { |result, (key, value)|
         
     | 
| 
      
 4 
     | 
    
         
            +
                  value = value.deep_stringify_keys if value.is_a?(Hash)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  result[(key.to_s rescue key) || key] = value
         
     | 
| 
      
 6 
     | 
    
         
            +
                  result
         
     | 
| 
      
 7 
     | 
    
         
            +
                }
         
     | 
| 
      
 8 
     | 
    
         
            +
              end unless Hash.method_defined?(:deep_stringify_keys)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def deep_stringify_keys!
         
     | 
| 
      
 11 
     | 
    
         
            +
                stringify_keys!
         
     | 
| 
      
 12 
     | 
    
         
            +
                each do |k, v|
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self[k] = self[k].deep_stringify_keys! if self[k].is_a?(Hash)
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
                self
         
     | 
| 
      
 16 
     | 
    
         
            +
              end unless Hash.method_defined?(:deep_stringify_keys!)
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def self.convert_hash_to_ordered_hash(object, deep = false)
         
     | 
| 
      
 19 
     | 
    
         
            +
                # Hash is ordered in Ruby 1.9!
         
     | 
| 
      
 20 
     | 
    
         
            +
                if RUBY_VERSION >= '1.9'
         
     | 
| 
      
 21 
     | 
    
         
            +
                  return object
         
     | 
| 
      
 22 
     | 
    
         
            +
                else
         
     | 
| 
      
 23 
     | 
    
         
            +
                  if object.is_a?(Hash)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    ActiveSupport::OrderedHash.new.tap do |map|
         
     | 
| 
      
 25 
     | 
    
         
            +
                      object.each { |k, v| map[k] = deep ? convert_hash_to_ordered_hash(v, deep) : v }
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  elsif deep && object.is_a?(Array)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    array = Array.new
         
     | 
| 
      
 29 
     | 
    
         
            +
                    object.each_with_index { |v, i| array[i] = convert_hash_to_ordered_hash(v, deep) }
         
     | 
| 
      
 30 
     | 
    
         
            +
                    return array
         
     | 
| 
      
 31 
     | 
    
         
            +
                  else
         
     | 
| 
      
 32 
     | 
    
         
            +
                    return object
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              def to_ordered_hash(deep = false)
         
     | 
| 
      
 38 
     | 
    
         
            +
                Hash.convert_hash_to_ordered_hash(self, deep)
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # > "a.b.c".to_hash("Some value")
         
     | 
| 
      
 2 
     | 
    
         
            +
            # => {"a"=>{"b"=>{"c"=>"Some value"}}}
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class String
         
     | 
| 
      
 5 
     | 
    
         
            +
              def to_hash(val=nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
                keys = self.split('.')
         
     | 
| 
      
 7 
     | 
    
         
            +
                Hash.new.tap do |hsh|
         
     | 
| 
      
 8 
     | 
    
         
            +
                  while keys.present? do
         
     | 
| 
      
 9 
     | 
    
         
            +
                    k = keys.shift
         
     | 
| 
      
 10 
     | 
    
         
            +
                    hsh[k.to_s] = keys.blank? ? val : Hash.new
         
     | 
| 
      
 11 
     | 
    
         
            +
                    hsh = hsh[k.to_s]
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,111 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "yaml/encoding"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "string"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "hash"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module I18n
         
     | 
| 
      
 6 
     | 
    
         
            +
              class TranslationSpawner
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                class CannotDecodeTranslationFilePath < StandardError;
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                attr_accessor_with_default :skip_locales, []
         
     | 
| 
      
 12 
     | 
    
         
            +
                attr_accessor_with_default :removable_prefixes, %w()
         
     | 
| 
      
 13 
     | 
    
         
            +
                attr_accessor_with_default :default_translations, {}
         
     | 
| 
      
 14 
     | 
    
         
            +
                attr_accessor :exception_handler, :key_translations_handler, :translations_handler, :file_path_decoder
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                private
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def translation_for_key(key, locale)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  if key_translations_handler.respond_to?(:call)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    key_translations_handler.call(key, locale, self)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  else
         
     | 
| 
      
 22 
     | 
    
         
            +
                    default_translation_for_key(key, locale)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def translation(key, locale)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  if translations_handler.respond_to?(:call)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    translations_handler.call(key, locale, self)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  else
         
     | 
| 
      
 30 
     | 
    
         
            +
                    default_translation(key, locale)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def decode_file_path(key, locale)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  if file_path_decoder.respond_to?(:call)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    file_path_decoder.call(key, locale, self)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  else
         
     | 
| 
      
 38 
     | 
    
         
            +
                    default_decode_file_path(key, locale)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def spawn_translation_key(key, locale, options, exception)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  I18n.available_locales.reject { |l| skip_locales.include?(l) }.each do |_locale|
         
     | 
| 
      
 44 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 45 
     | 
    
         
            +
                      decode_file_path(key, _locale).tap do |path|
         
     | 
| 
      
 46 
     | 
    
         
            +
                        translations_hash = YAML::load_file(path)
         
     | 
| 
      
 47 
     | 
    
         
            +
                        hash_to_merge = "#{_locale.to_s}.#{key}".to_hash(translation(key, _locale.to_s)).deep_stringify_keys!
         
     | 
| 
      
 48 
     | 
    
         
            +
                        translations_hash = translations_hash.deep_merge(hash_to_merge).to_ordered_hash
         
     | 
| 
      
 49 
     | 
    
         
            +
                        File.open(path, 'w') { |f| f.write(YAML.unescape(translations_hash.ya2yaml)) }
         
     | 
| 
      
 50 
     | 
    
         
            +
                      end
         
     | 
| 
      
 51 
     | 
    
         
            +
                    rescue CannotDecodeTranslationFilePath
         
     | 
| 
      
 52 
     | 
    
         
            +
                      Rails.logger.info "=== Cannot access translation file for #{key.to_s}"
         
     | 
| 
      
 53 
     | 
    
         
            +
                      return(options[:rescue_format] == :html ? exception.html_message : exception.message)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                  translation(key, locale.to_s)
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                public
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def default_decode_file_path(key, locale)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  if File.file?(path = File.join(Rails.root, "config/locales", "#{locale.to_s}.yml"))
         
     | 
| 
      
 63 
     | 
    
         
            +
                    path
         
     | 
| 
      
 64 
     | 
    
         
            +
                  else
         
     | 
| 
      
 65 
     | 
    
         
            +
                    raise CannotDecodeTranslationFilePath
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                def default_translation(key, locale)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  if ranslations_handler.respond_to?(:call)
         
     | 
| 
      
 71 
     | 
    
         
            +
                     translations_handler(key, locale, self)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  else
         
     | 
| 
      
 73 
     | 
    
         
            +
                    _key = key.dup
         
     | 
| 
      
 74 
     | 
    
         
            +
                    while _key.present?
         
     | 
| 
      
 75 
     | 
    
         
            +
                      if (val = default_translations[_key]).present?
         
     | 
| 
      
 76 
     | 
    
         
            +
                        if val.is_a?(Hash)
         
     | 
| 
      
 77 
     | 
    
         
            +
                          return(val[locale].present? ? val[locale] : translation_for_key(key, locale))
         
     | 
| 
      
 78 
     | 
    
         
            +
                        else
         
     | 
| 
      
 79 
     | 
    
         
            +
                          return(val.to_s)
         
     | 
| 
      
 80 
     | 
    
         
            +
                        end
         
     | 
| 
      
 81 
     | 
    
         
            +
                      else
         
     | 
| 
      
 82 
     | 
    
         
            +
                        _key.sub!(/([a-zA-Z0-9_]*\.?)/, '')
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
                    translation_for_key(key, locale)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def default_translation_for_key(key, locale)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  key.split('.').last.sub(/\A#{removable_prefixes.map { |prefix| prefix+'_' }.join('|')}/, '').humanize
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                def call(exception, locale, key, options)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  if exception_handler.respond_to?(:call)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    exception_handler.call(exception, locale, key, self, options)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  else
         
     | 
| 
      
 97 
     | 
    
         
            +
                    handle_exception(exception, locale, key, options)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                def handle_exception(exception, locale, key, options)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  case exception
         
     | 
| 
      
 103 
     | 
    
         
            +
                    when I18n::MissingTranslationData
         
     | 
| 
      
 104 
     | 
    
         
            +
                      spawn_translation_key(key, locale, options, exception)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    else
         
     | 
| 
      
 106 
     | 
    
         
            +
                      raise exception
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: i18n_translation_spawner
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 29
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 9 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 11 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 13 
     | 
    
         
            +
            - "B\xC5\x82a\xC5\xBCej --Stevo-- Kosmowski"
         
     | 
| 
      
 14 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 16 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2011-09-09 00:00:00 Z
         
     | 
| 
      
 19 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 20 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 21 
     | 
    
         
            +
              name: ya2yaml
         
     | 
| 
      
 22 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 23 
     | 
    
         
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 24 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 25 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 26 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 27 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 28 
     | 
    
         
            +
                    hash: 13
         
     | 
| 
      
 29 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 30 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 31 
     | 
    
         
            +
                    - 3
         
     | 
| 
      
 32 
     | 
    
         
            +
                    version: "0.3"
         
     | 
| 
      
 33 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 34 
     | 
    
         
            +
              version_requirements: *id001
         
     | 
| 
      
 35 
     | 
    
         
            +
            description: Gem for automatic creation i18n keys in your YAML files as you develop
         
     | 
| 
      
 36 
     | 
    
         
            +
            email: b.kosmowski@selleo.com
         
     | 
| 
      
 37 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 44 
     | 
    
         
            +
            - lib/i18n_translation_spawner/hash.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - lib/i18n_translation_spawner/string.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - lib/i18n_translation_spawner.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            homepage: http://rubygems.org/gems/i18n_translation_spawner
         
     | 
| 
      
 48 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 51 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 54 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 55 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 56 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 58 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 59 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 60 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 61 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 62 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 63 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 64 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 65 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 66 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 67 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 68 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 69 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 70 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 71 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 72 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 73 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 76 
     | 
    
         
            +
            rubygems_version: 1.8.9
         
     | 
| 
      
 77 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 78 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 79 
     | 
    
         
            +
            summary: Automatic i18n keys generator
         
     | 
| 
      
 80 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     |