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
|
+
|