translation 1.18 → 1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +43 -11
- data/lib/translation.rb +4 -1
- data/lib/translation_io/client/base_operation/save_new_yaml_files_step.rb +1 -1
- data/lib/translation_io/client/base_operation/save_special_yaml_files_step.rb +23 -17
- data/lib/translation_io/client/init_operation.rb +2 -2
- data/lib/translation_io/client/init_operation/cleanup_yaml_files_step.rb +17 -11
- data/lib/translation_io/client/sync_operation/apply_yaml_source_edits_step.rb +18 -2
- data/lib/translation_io/config.rb +40 -11
- data/lib/translation_io/flat_hash.rb +5 -1
- data/lib/translation_io/railtie.rb +5 -1
- data/lib/translation_io/yaml_conversion.rb +8 -1
- data/lib/translation_io/yaml_entry.rb +3 -3
- metadata +2 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff2388659bd454e1ff1cbcad7133161a66902007d08e4735b80c628289665c15
|
4
|
+
data.tar.gz: d9a4222b6014f21dc2b29cc9de1afb60d725301d6d93a9cd7f0ba5b0cbc8d2e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 917f60afd4befcabb144943a3b9ebd26d2d4cd372ef286432d0bc0c03aafc9aff6bae7e4b956abcc11506f35be33e752cd011ff10f1b8a7b77e84038a0bf783f
|
7
|
+
data.tar.gz: 8a9b12a2c66a7f060f2861150ad171ab4ebeb94b87fb18bc4763c2529871f8b58963c221cd9844844a3ef56dd9e4e32c262cf85b5df751a650f19e97e0de2a7e
|
data/README.md
CHANGED
@@ -46,6 +46,7 @@ Table of contents
|
|
46
46
|
* [Gems with GetText strings](#gems-with-gettext-strings)
|
47
47
|
* [Custom localization key prefixes](#custom-localization-key-prefixes)
|
48
48
|
* [Paths where locales are stored (not recommended)](#paths-where-locales-are-stored-not-recommended)
|
49
|
+
* [GetText Object Class Monkey-Patching](#gettext-object-class-monkey-patching)
|
49
50
|
* [Pure Ruby (without Rails)](#pure-ruby-without-rails)
|
50
51
|
* [Testing](#testing)
|
51
52
|
* [Contributing](#contributing)
|
@@ -316,14 +317,14 @@ For example:
|
|
316
317
|
TranslationIO.configure do |config|
|
317
318
|
...
|
318
319
|
config.ignored_key_prefixes = [
|
319
|
-
'number.human
|
320
|
-
'admin
|
321
|
-
'errors.messages
|
322
|
-
'activerecord.errors.messages
|
323
|
-
'will_paginate
|
324
|
-
'helpers.page_entries_info
|
325
|
-
'views.pagination
|
326
|
-
'enumerize.visibility
|
320
|
+
'number.human',
|
321
|
+
'admin',
|
322
|
+
'errors.messages',
|
323
|
+
'activerecord.errors.messages',
|
324
|
+
'will_paginate',
|
325
|
+
'helpers.page_entries_info',
|
326
|
+
'views.pagination',
|
327
|
+
'enumerize.visibility'
|
327
328
|
]
|
328
329
|
...
|
329
330
|
end
|
@@ -403,6 +404,30 @@ TranslationIO.configure do |config|
|
|
403
404
|
end
|
404
405
|
```
|
405
406
|
|
407
|
+
### GetText Object Class Monkey-Patching
|
408
|
+
|
409
|
+
GetText methods (`_('')`, etc.) are available everywhere in your application.
|
410
|
+
This is made by extending the global `Object` class.
|
411
|
+
|
412
|
+
You can disable the built-in `Object` monkey-patching if you
|
413
|
+
prefer a more granular approach:
|
414
|
+
|
415
|
+
```ruby
|
416
|
+
TranslationIO.configure do |config|
|
417
|
+
...
|
418
|
+
config.gettext_object_delegate = false
|
419
|
+
...
|
420
|
+
end
|
421
|
+
```
|
422
|
+
|
423
|
+
Don't forget to manually include the GetText methods where needed:
|
424
|
+
|
425
|
+
```ruby
|
426
|
+
class Contact < ApplicationRecord
|
427
|
+
extend TranslationIO::Proxy
|
428
|
+
end
|
429
|
+
```
|
430
|
+
|
406
431
|
## Pure Ruby (without Rails)
|
407
432
|
|
408
433
|
This gem was created specifically for Rails, but you can also use it in a pure Ruby project by making some arrangements:
|
@@ -505,9 +530,16 @@ Credits: [@deecewan](https://github.com/deecewan)
|
|
505
530
|
|
506
531
|
### Others
|
507
532
|
|
508
|
-
If you want to create a new client for your favorite language or framework,
|
509
|
-
|
510
|
-
|
533
|
+
If you want to create a new client for your favorite language or framework, please read our
|
534
|
+
[Create a Translation.io Library](https://translation.io/docs/create-library)
|
535
|
+
guide and use the special
|
536
|
+
[init](https://translation.io/docs/create-library#initialization) and
|
537
|
+
[sync](https://translation.io/docs/create-library#synchronization) endpoints.
|
538
|
+
|
539
|
+
You can also use the more [traditional API](https://translation.io/docs/api).
|
540
|
+
|
541
|
+
Feel free to contact us on [contact@translation.io](mailto:contact@translation.io) if
|
542
|
+
you need some help or if you want to share your library.
|
511
543
|
|
512
544
|
## License
|
513
545
|
|
data/lib/translation.rb
CHANGED
@@ -51,7 +51,10 @@ module TranslationIO
|
|
51
51
|
end
|
52
52
|
|
53
53
|
Proxy.textdomain(@config.text_domain)
|
54
|
-
|
54
|
+
|
55
|
+
if @config.gettext_object_delegate
|
56
|
+
Object.delegate *GETTEXT_METHODS, :to => Proxy
|
57
|
+
end
|
55
58
|
end
|
56
59
|
|
57
60
|
@client = Client.new(@config.api_key, @config.endpoint)
|
@@ -19,7 +19,7 @@ module TranslationIO
|
|
19
19
|
|
20
20
|
yaml_data = YAMLConversion.get_yaml_data_from_po_data(@parsed_response["yaml_po_data_#{target_locale}"], target_locale)
|
21
21
|
|
22
|
-
top_comment =
|
22
|
+
top_comment = <<-EOS
|
23
23
|
# WARNING. THIS FILE WAS AUTO-GENERATED BY THE TRANSLATION GEM.
|
24
24
|
# IF YOU UPDATE IT, YOUR CHANGES WILL BE LOST AT THE NEXT SYNC.
|
25
25
|
#
|
@@ -24,6 +24,8 @@ module TranslationIO
|
|
24
24
|
YamlEntry.localization?(key, value)
|
25
25
|
end
|
26
26
|
|
27
|
+
params = {}
|
28
|
+
|
27
29
|
@target_locales.each do |target_locale|
|
28
30
|
yaml_path = File.join(@yaml_locales_path, "localization.#{target_locale}.yml")
|
29
31
|
|
@@ -35,32 +37,36 @@ module TranslationIO
|
|
35
37
|
|
36
38
|
yaml_data = YAMLConversion.get_yaml_data_from_flat_translations(target_flat_special_translations)
|
37
39
|
|
38
|
-
|
39
|
-
file.write(self.class.top_comment)
|
40
|
-
file.write(yaml_data)
|
41
|
-
end
|
42
|
-
end
|
40
|
+
params["yaml_data_#{target_locale}"] = yaml_data
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
42
|
+
# To have a localization.xx.yml file during tests (without call to backend)
|
43
|
+
if TranslationIO.config.test
|
44
|
+
if YAML::load(yaml_data).present?
|
45
|
+
File.open(yaml_path, 'wb') do |file|
|
46
|
+
file.write(self.class.top_comment)
|
47
|
+
file.write(yaml_data)
|
48
|
+
end
|
49
|
+
end
|
50
50
|
end
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
+
TranslationIO.info "Collecting YAML localization entries from server."
|
53
54
|
|
55
|
+
# To have a localization.xx.yml file with call to backend
|
56
|
+
if !TranslationIO.config.test
|
54
57
|
uri = URI("#{TranslationIO.client.endpoint}/projects/#{TranslationIO.client.api_key}/fill_yaml_localizations")
|
55
58
|
parsed_response = BaseOperation.perform_request(uri, params)
|
56
59
|
|
57
|
-
|
60
|
+
if !parsed_response.nil?
|
58
61
|
@target_locales.each do |target_locale|
|
59
62
|
yaml_path = File.join(@yaml_locales_path, "localization.#{target_locale}.yml")
|
63
|
+
yaml_data = parsed_response["yaml_data_#{target_locale}"]
|
60
64
|
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
if yaml_data.present? && YAML::load(yaml_data).present?
|
66
|
+
File.open(yaml_path, 'wb') do |file|
|
67
|
+
file.write(self.class.top_comment)
|
68
|
+
file.write(yaml_data)
|
69
|
+
end
|
64
70
|
end
|
65
71
|
end
|
66
72
|
end
|
@@ -68,7 +74,7 @@ module TranslationIO
|
|
68
74
|
end
|
69
75
|
|
70
76
|
def self.top_comment
|
71
|
-
|
77
|
+
<<-EOS
|
72
78
|
# THIS FILE CONTAINS LOCALIZATION KEYS : date and number formats, number precisions,
|
73
79
|
# number separators and all non-textual values depending on the language.
|
74
80
|
# These values must not reach the translator, so they are separated in this file.
|
@@ -62,7 +62,7 @@ module TranslationIO
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def warn_source_locale_unfound(source_locale, all_used_yaml_locales)
|
65
|
-
is_source_locale_unfound = !
|
65
|
+
is_source_locale_unfound = !all_used_yaml_locales.include?(source_locale)
|
66
66
|
|
67
67
|
if is_source_locale_unfound
|
68
68
|
puts
|
@@ -88,7 +88,7 @@ module TranslationIO
|
|
88
88
|
puts
|
89
89
|
puts "----------"
|
90
90
|
puts "Your `config.target_locales` are [#{target_locales.sort.join(', ')}]."
|
91
|
-
puts "But we haven't found any YAML key for [#{target_locales_unfound.join(', ')}], is this normal?"
|
91
|
+
puts "But we haven't found any YAML key for [#{target_locales_unfound.sort.join(', ')}], is this normal?"
|
92
92
|
puts "If not, check that you haven't misspelled the locale (ex. 'en-GB' instead of 'en')."
|
93
93
|
puts "----------"
|
94
94
|
puts "Do you want to continue? (y/N)"
|
@@ -13,22 +13,28 @@ module TranslationIO
|
|
13
13
|
@yaml_file_paths.each do |locale_file_path|
|
14
14
|
if locale_file_removable?(locale_file_path)
|
15
15
|
if File.exist?(locale_file_path)
|
16
|
-
content_hash
|
16
|
+
content_hash = YAML::load(File.read(locale_file_path)) || {}
|
17
|
+
source_content_hash = content_hash.select { |k| k.to_s == @source_locale.to_s }
|
17
18
|
|
18
|
-
if
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
if new_content_hash.keys.any?
|
19
|
+
if source_content_hash.empty?
|
20
|
+
TranslationIO.info "Removing #{locale_file_path}", 2, 2
|
21
|
+
FileUtils.rm(locale_file_path)
|
22
|
+
elsif content_hash != source_content_hash # in case of mixed languages in source YAML file
|
25
23
|
TranslationIO.info "Rewriting #{locale_file_path}", 2, 2
|
24
|
+
|
25
|
+
if TranslationIO.config.yaml_line_width
|
26
|
+
file_content = source_content_hash.to_yaml(:line_width => TranslationIO.config.yaml_line_width)
|
27
|
+
else
|
28
|
+
file_content = source_content_hash.to_yaml
|
29
|
+
end
|
30
|
+
|
31
|
+
file_content = file_content.gsub(/ $/, '') # remove trailing spaces
|
32
|
+
|
26
33
|
File.open(locale_file_path, 'wb') do |file|
|
27
|
-
file.write(
|
34
|
+
file.write(file_content)
|
28
35
|
end
|
29
36
|
else
|
30
|
-
|
31
|
-
FileUtils.rm(locale_file_path)
|
37
|
+
# don't touch source
|
32
38
|
end
|
33
39
|
end
|
34
40
|
end
|
@@ -31,8 +31,10 @@ module TranslationIO
|
|
31
31
|
if locale_file_path_in_project?(file_path)
|
32
32
|
flat_yaml_hash[key] = source_edit['new_text']
|
33
33
|
|
34
|
+
file_content = to_hash_to_yaml(flat_yaml_hash)
|
35
|
+
|
34
36
|
File.open(file_path, 'w') do |f|
|
35
|
-
f.write(
|
37
|
+
f.write(file_content)
|
36
38
|
end
|
37
39
|
else # override source text of gem
|
38
40
|
yaml_path = File.join(TranslationIO.config.yaml_locales_path, "#{@source_locale}.yml")
|
@@ -47,8 +49,10 @@ module TranslationIO
|
|
47
49
|
|
48
50
|
flat_yaml_hash["#{@source_locale}.#{source_edit['key']}"] = source_edit['new_text']
|
49
51
|
|
52
|
+
file_content = to_hash_to_yaml(flat_yaml_hash)
|
53
|
+
|
50
54
|
File.open(yaml_path, 'w') do |f|
|
51
|
-
f.write(
|
55
|
+
f.write(file_content)
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
@@ -72,6 +76,18 @@ module TranslationIO
|
|
72
76
|
|
73
77
|
private
|
74
78
|
|
79
|
+
def to_hash_to_yaml(flat_yaml_hash)
|
80
|
+
yaml_hash = FlatHash.to_hash(flat_yaml_hash)
|
81
|
+
|
82
|
+
if TranslationIO.config.yaml_line_width
|
83
|
+
content = yaml_hash.to_yaml(:line_width => TranslationIO.config.yaml_line_width)
|
84
|
+
else
|
85
|
+
content = yaml_hash.to_yaml
|
86
|
+
end
|
87
|
+
|
88
|
+
content.gsub(/ $/, '') # remove trailing spaces
|
89
|
+
end
|
90
|
+
|
75
91
|
def metadata_timestamp
|
76
92
|
if File.exist?(TranslationIO.config.metadata_path)
|
77
93
|
metadata_content = File.read(TranslationIO.config.metadata_path)
|
@@ -13,9 +13,12 @@ module TranslationIO
|
|
13
13
|
attr_accessor :yaml_locales_path
|
14
14
|
attr_accessor :ignored_key_prefixes
|
15
15
|
attr_accessor :localization_key_prefixes
|
16
|
+
attr_accessor :yaml_line_width
|
16
17
|
|
17
18
|
attr_accessor :disable_gettext
|
18
19
|
|
20
|
+
attr_accessor :gettext_object_delegate
|
21
|
+
|
19
22
|
attr_accessor :locales_path
|
20
23
|
|
21
24
|
attr_accessor :ignored_source_paths
|
@@ -67,17 +70,25 @@ module TranslationIO
|
|
67
70
|
# Cf. https://github.com/translation/rails#custom-localization-key-prefixes
|
68
71
|
self.localization_key_prefixes = []
|
69
72
|
|
73
|
+
# Define max line width of generated YAML files:
|
74
|
+
# Can be nil (default behaviour of Ruby version), -1 (no wrapping) or positive integer (wrapping)
|
75
|
+
# Cf. https://github.com/translation/rails/issues/19
|
76
|
+
self.yaml_line_width = nil
|
77
|
+
|
70
78
|
#######
|
71
79
|
# GetText options
|
72
80
|
#######
|
73
81
|
|
74
82
|
self.disable_gettext = false
|
75
83
|
|
84
|
+
# Cf. https://github.com/translation/rails#gettext-object-class-monkey-patching
|
85
|
+
self.gettext_object_delegate = true
|
86
|
+
|
76
87
|
# GetText directory for PO and MO files
|
77
88
|
self.locales_path = File.join('config', 'locales', 'gettext')
|
78
89
|
|
79
90
|
# These paths and files will not be parsed for GetText entries
|
80
|
-
self.ignored_source_paths = ['vendor/', 'tmp/', 'node_modules/', 'logs/', '.git/']
|
91
|
+
self.ignored_source_paths = ['vendor/', 'tmp/', 'node_modules/', 'logs/', '.git/', 'public/', 'private/']
|
81
92
|
self.ignored_source_files = []
|
82
93
|
|
83
94
|
# These gems will be parsed by GetText (use gem names)
|
@@ -130,27 +141,45 @@ module TranslationIO
|
|
130
141
|
end
|
131
142
|
|
132
143
|
def source_files_for_formats(formats)
|
133
|
-
file_paths =
|
144
|
+
file_paths = []
|
145
|
+
root_paths = ['.']
|
134
146
|
|
135
|
-
# Add
|
147
|
+
# Add gem paths that need to be parsed by GetText ("parsed_gem" option)
|
136
148
|
parsed_gems.each do |gem_name|
|
137
149
|
if Gem.loaded_specs[gem_name]
|
138
|
-
|
139
|
-
file_paths += Dir["#{gem_path}/**/*.{#{formats.join(',')}}"]
|
150
|
+
root_paths << Gem.loaded_specs[gem_name].full_gem_path
|
140
151
|
end
|
141
152
|
end
|
142
153
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
154
|
+
root_paths.each do |root_path|
|
155
|
+
Pathname.new(root_path).find do |path|
|
156
|
+
if path.directory?
|
157
|
+
if is_ignored_path?(path)
|
158
|
+
Find.prune
|
159
|
+
end
|
160
|
+
else
|
161
|
+
if formats.include?(path.extname[1..-1]) && !is_ignored_file?(path)
|
162
|
+
file_paths << path.to_s
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
149
166
|
end
|
150
167
|
|
151
168
|
file_paths
|
152
169
|
end
|
153
170
|
|
171
|
+
def is_ignored_path?(path)
|
172
|
+
ignored_source_paths.any? do |ignored_source_path|
|
173
|
+
path == Pathname.new(ignored_source_path).cleanpath
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def is_ignored_file?(path)
|
178
|
+
ignored_source_files.any? do |ignored_source_file|
|
179
|
+
path == Pathname.new(ignored_source_file).cleanpath
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
154
183
|
def to_s
|
155
184
|
"API Key: #{api_key} | Languages: #{source_locale} => [#{target_locales.join(', ')}]"
|
156
185
|
end
|
@@ -7,9 +7,13 @@ module TranslationIO
|
|
7
7
|
get_flat_hash_for_level(hash)
|
8
8
|
end
|
9
9
|
|
10
|
-
def to_hash(flat_hash)
|
10
|
+
def to_hash(flat_hash, remove_empty_keys = false)
|
11
11
|
hash = {}
|
12
12
|
|
13
|
+
if remove_empty_keys
|
14
|
+
flat_hash = flat_hash.reject { |k, v| v.nil? && !k.end_with?(']') }
|
15
|
+
end
|
16
|
+
|
13
17
|
flat_hash.each_pair do |key, value|
|
14
18
|
build_hash_with_flat(hash, key, value)
|
15
19
|
end
|
@@ -49,8 +49,12 @@ if defined?(GetText)
|
|
49
49
|
begin
|
50
50
|
parse_path(path, po)
|
51
51
|
rescue SystemExit => e
|
52
|
-
# puts(_("Error parsing %{path}") % {:path => path})
|
53
52
|
puts
|
53
|
+
puts "---------------"
|
54
|
+
puts "Error while parsing this file for GetText: #{path}"
|
55
|
+
puts "Are you sure the file is correctly formatted?"
|
56
|
+
puts "Feel free to contact us to get some help: contact@translation.io"
|
57
|
+
puts "---------------"
|
54
58
|
puts
|
55
59
|
end
|
56
60
|
end
|
@@ -37,7 +37,14 @@ module TranslationIO
|
|
37
37
|
|
38
38
|
def get_yaml_data_from_flat_translations(flat_translations)
|
39
39
|
translations = FlatHash.to_hash(flat_translations)
|
40
|
-
|
40
|
+
|
41
|
+
if TranslationIO.config.yaml_line_width
|
42
|
+
data = translations.to_yaml(:line_width => TranslationIO.config.yaml_line_width)
|
43
|
+
else
|
44
|
+
data = translations.to_yaml
|
45
|
+
end
|
46
|
+
|
47
|
+
data.gsub(/ $/, '') # remove trailing spaces
|
41
48
|
end
|
42
49
|
|
43
50
|
end
|
@@ -2,7 +2,7 @@ module TranslationIO
|
|
2
2
|
module YamlEntry
|
3
3
|
|
4
4
|
IGNORED_KEY_PREFIXES = [
|
5
|
-
'faker
|
5
|
+
'faker'
|
6
6
|
]
|
7
7
|
|
8
8
|
LOCALIZATION_KEY_PREFIXES = [
|
@@ -31,7 +31,7 @@ module TranslationIO
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def ignored?(key)
|
34
|
-
key.present? && ignored_key_prefixes.any? { |p| key_without_locale(key).
|
34
|
+
key.present? && ignored_key_prefixes.any? { |p| key_without_locale(key).match(/^#{p}\b/) != nil }
|
35
35
|
end
|
36
36
|
|
37
37
|
def localization?(key, value)
|
@@ -40,7 +40,7 @@ module TranslationIO
|
|
40
40
|
|
41
41
|
def localization_prefix?(key)
|
42
42
|
localization_key_prefixes.any? do |prefix|
|
43
|
-
key_without_locale(key).
|
43
|
+
key_without_locale(key).match(/^#{prefix}\b/) != nil
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: translation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.19'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Hoste
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-
|
12
|
+
date: 2019-09-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gettext
|
@@ -80,9 +80,6 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '4.1'
|
83
|
-
- - "<"
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '7.0'
|
86
83
|
type: :development
|
87
84
|
prerelease: false
|
88
85
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,9 +87,6 @@ dependencies:
|
|
90
87
|
- - ">="
|
91
88
|
- !ruby/object:Gem::Version
|
92
89
|
version: '4.1'
|
93
|
-
- - "<"
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '7.0'
|
96
90
|
description: Localize your app using either t(".keys") or _("source text") and type
|
97
91
|
"rake translation:sync" to synchronize with your translators on Translation.io.
|
98
92
|
email: contact@translation.io
|