translation 1.17 → 1.18

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 12113892c41a14c8d164e01d9d9c2339a92436f8
4
- data.tar.gz: 403abefb4765377f59d145bb39fcfe477099cde3
2
+ SHA256:
3
+ metadata.gz: 2e21e49a9aac4d9fec598b037a0411544b374003fd08ba033bcd3c4f27e7c118
4
+ data.tar.gz: 06de16c4833d428ba8ab90b441dda1c58b130ef1e5c03294e34971a262bec576
5
5
  SHA512:
6
- metadata.gz: c67cb77f2af77d56b26cfa9869196df3d62f478c3236a11cfdc5fa180d500c5795bbaab08a75920d5e88a1bd48c46a54d97e290dc48772b9ef1920d54582e7a6
7
- data.tar.gz: 196ada47e46d5bebdb347b314ca02f3035018341b18d9d57fa4ef39943705588546b1c96173af53ab0f543e1eb7bdaac4b8b788733806f371c6dc768405db555
6
+ metadata.gz: 1e0c55227bb61dba3b05273b2ee5289bbc4b74ce290d4fce1a7f5aa495da3db60cd56a31eaa5ffca276fc1c1c7c48469ffc0d2cf7addd51ebcbe45bbee89d238
7
+ data.tar.gz: 484b10782d68c7f626c3c68c337087223ac28610d622fca6b08300642a2cb8acb4ee185ed7903cd19d3ee72130ce1dda5168b26127f05ed52f8f3eeab3d07115
data/README.md CHANGED
@@ -40,9 +40,10 @@ Table of contents
40
40
  * [Locally](#locally)
41
41
  * [Continuous Integration](#continuous-integration)
42
42
  * [Advanced Configuration Options](#advanced-configuration-options)
43
- * [Disable GetText](#disable-gettext)
43
+ * [Disable GetText or YAML](#disable-gettext-or-yaml)
44
44
  * [Ignored YAML keys](#ignored-yaml-keys)
45
45
  * [Source file formats (for GetText)](#source-file-formats-for-gettext)
46
+ * [Gems with GetText strings](#gems-with-gettext-strings)
46
47
  * [Custom localization key prefixes](#custom-localization-key-prefixes)
47
48
  * [Paths where locales are stored (not recommended)](#paths-where-locales-are-stored-not-recommended)
48
49
  * [Pure Ruby (without Rails)](#pure-ruby-without-rails)
@@ -265,9 +266,9 @@ More examples here: https://translation.io/blog/rails-i18n-with-locale
265
266
 
266
267
  ## Continuous Integration
267
268
 
268
- If you want fresh translations in your Continuous Integration workflow, you may find yourself calling `bundle exec rake translation:sync` very frequently.
269
+ If you want fresh translations in your Continuous Integration workflow, you may find yourself calling `bundle exec rake translation:sync` very frequently.
269
270
 
270
- Since this task can't be concurrently executed (we have a [mutex](https://en.wikipedia.org/wiki/Mutual_exclusion) strategy with a queue but it returns an error under heavy load), we implemented this threadsafe readonly task:
271
+ Since this task can't be concurrently executed (we have a [mutex](https://en.wikipedia.org/wiki/Mutual_exclusion) strategy with a queue but it returns an error under heavy load), we implemented this threadsafe readonly task:
271
272
 
272
273
  ```bash
273
274
  $ bundle exec rake translation:sync_readonly
@@ -281,12 +282,9 @@ The `TranslationIO.configure` block in `config/initializers/translation.rb` can
281
282
 
282
283
  Some options are described below but for an exhaustive list, please refer to [config.rb](https://github.com/translation/rails/blob/master/lib/translation_io/config.rb).
283
284
 
284
- ### Disable GetText
285
+ ### Disable GetText or YAML
285
286
 
286
- Sometimes, you only want to use YAML and don't want to be bothered by GetText at all.
287
- For these cases, you just have to add `disable_gettext` in the config file.
288
-
289
- For example:
287
+ If you want to only use YAML files and totally ignore GetText syntax, use:
290
288
 
291
289
  ```ruby
292
290
  TranslationIO.configure do |config|
@@ -296,6 +294,17 @@ TranslationIO.configure do |config|
296
294
  end
297
295
  ```
298
296
 
297
+ In contrast, if you only want to synchronize GetText files and leave the YAML
298
+ files unchanged, use:
299
+
300
+ ```ruby
301
+ TranslationIO.configure do |config|
302
+ ...
303
+ config.disable_yaml = true
304
+ ...
305
+ end
306
+ ```
307
+
299
308
  ### Ignored YAML keys
300
309
 
301
310
  Sometimes you would like to ignore some YAML keys coming from gems or so.
@@ -342,6 +351,19 @@ TranslationIO.configure do |config|
342
351
  end
343
352
  ```
344
353
 
354
+ ### Gems with GetText strings
355
+
356
+ Public gems usually don't make use of GetText strings, but if you created and localized your own gems
357
+ with the GetText syntax, you'll want to be able to synchronize them:
358
+
359
+ ```ruby
360
+ TranslationIO.configure do |config|
361
+ ...
362
+ config.parsed_gems = ['your_gem_name']
363
+ ...
364
+ end
365
+ ```
366
+
345
367
  ### Custom localization key prefixes
346
368
 
347
369
  Rails YAML files contain not only translation strings but also localization values (integers, arrays, booleans)
data/lib/translation.rb CHANGED
@@ -5,8 +5,6 @@ module TranslationIO
5
5
  :nsgettext, :pgettext, :npgettext, :sgettext, :ngettext, :gettext,
6
6
  :np_, :ns_, :Nn_, :n_, :p_, :s_, :N_, :_
7
7
  ]
8
-
9
- TEXT_DOMAIN = 'app'
10
8
  end
11
9
 
12
10
  require 'translation_io/config'
@@ -33,7 +31,7 @@ module TranslationIO
33
31
 
34
32
  yield @config
35
33
 
36
- unless @config.disable_gettext
34
+ if !@config.disable_gettext
37
35
  require_gettext_dependencies
38
36
  add_missing_locales
39
37
  add_parser_for_erb_source_formats(@config.erb_source_formats)
@@ -45,12 +43,14 @@ module TranslationIO
45
43
  # include is private until Ruby 2.1
46
44
  Proxy.send(:include, GetText)
47
45
 
48
- Proxy.bindtextdomain(TEXT_DOMAIN, {
49
- :path => @config.locales_path,
50
- :output_charset => @config.charset
51
- })
46
+ @config.bound_text_domains.each do |bound_text_domain|
47
+ Proxy.bindtextdomain(bound_text_domain, {
48
+ :path => @config.locales_path,
49
+ :output_charset => @config.charset
50
+ })
51
+ end
52
52
 
53
- Proxy.textdomain(TEXT_DOMAIN)
53
+ Proxy.textdomain(@config.text_domain)
54
54
  Object.delegate *GETTEXT_METHODS, :to => Proxy
55
55
  end
56
56
 
@@ -9,8 +9,10 @@ module TranslationIO
9
9
  def run
10
10
  TranslationIO.info "Creating new MO files."
11
11
 
12
- Dir["#{@locales_path}/*/#{TEXT_DOMAIN}.po"].each do |po_path|
13
- mo_path = "#{File.dirname(po_path)}/LC_MESSAGES/app.mo"
12
+ text_domain = TranslationIO.config.text_domain
13
+
14
+ Dir["#{@locales_path}/*/#{text_domain}.po"].each do |po_path|
15
+ mo_path = "#{File.dirname(po_path)}/LC_MESSAGES/#{text_domain}.mo"
14
16
  TranslationIO.info mo_path, 2, 2
15
17
  FileUtils.mkdir_p(File.dirname(mo_path))
16
18
  GetText::Tools::MsgFmt.run(po_path, '-o', mo_path)
@@ -11,9 +11,11 @@ module TranslationIO
11
11
  def run
12
12
  TranslationIO.info "Saving new PO files."
13
13
 
14
+ text_domain = TranslationIO.config.text_domain
15
+
14
16
  @target_locales.each do |target_locale|
15
17
  if @parsed_response.has_key?("po_data_#{target_locale}")
16
- po_path = File.join(@locales_path, Locale::Tag.parse(target_locale).to_s, "#{TEXT_DOMAIN}.po")
18
+ po_path = File.join(@locales_path, Locale::Tag.parse(target_locale).to_s, "#{text_domain}.po")
17
19
  FileUtils.mkdir_p(File.dirname(po_path))
18
20
  TranslationIO.info po_path, 2, 2
19
21
 
@@ -19,7 +19,7 @@ module TranslationIO
19
19
  yaml_locales_path = config.yaml_locales_path
20
20
  yaml_file_paths = config.yaml_file_paths
21
21
 
22
- unless config.disable_gettext
22
+ if !config.disable_gettext
23
23
  BaseOperation::DumpMarkupGettextKeysStep.new(haml_source_files, :haml).run
24
24
  BaseOperation::DumpMarkupGettextKeysStep.new(slim_source_files, :slim).run
25
25
  end
@@ -27,27 +27,34 @@ module TranslationIO
27
27
  UpdatePotFileStep.new(pot_path, source_files + erb_source_files).run(params)
28
28
  UpdateAndCollectPoFilesStep.new(target_locales, pot_path, locales_path).run(params)
29
29
 
30
- create_yaml_pot_files_step = CreateYamlPoFilesStep.new(source_locale, target_locales, yaml_file_paths)
31
- create_yaml_pot_files_step.run(params)
30
+ if !config.disable_yaml
31
+ create_yaml_pot_files_step = CreateYamlPoFilesStep.new(source_locale, target_locales, yaml_file_paths)
32
+ create_yaml_pot_files_step.run(params)
32
33
 
33
- all_used_yaml_locales = create_yaml_pot_files_step.all_used_yaml_locales.to_a.map(&:to_s).sort
34
+ all_used_yaml_locales = create_yaml_pot_files_step.all_used_yaml_locales.to_a.map(&:to_s).sort
34
35
 
35
- warn_source_locale_unfound(source_locale, all_used_yaml_locales)
36
- warn_target_locale_unfound(target_locales, all_used_yaml_locales)
36
+ warn_source_locale_unfound(source_locale, all_used_yaml_locales)
37
+ warn_target_locale_unfound(target_locales, all_used_yaml_locales)
38
+ end
37
39
 
38
40
  TranslationIO.info "Sending data to server (it may take some time, please be patient. Sync will be faster)."
39
41
 
40
42
  uri = URI("#{client.endpoint}/projects/#{client.api_key}/init")
41
43
  parsed_response = BaseOperation.perform_request(uri, params)
42
44
 
43
- unless parsed_response.nil?
44
- BaseOperation::SaveNewPoFilesStep.new(target_locales, locales_path, parsed_response).run
45
- BaseOperation::SaveNewYamlFilesStep.new(target_locales, yaml_locales_path, parsed_response).run
46
- BaseOperation::SaveSpecialYamlFilesStep.new(source_locale, target_locales, yaml_locales_path, yaml_file_paths).run
47
- CleanupYamlFilesStep.new(source_locale, target_locales, yaml_file_paths, yaml_locales_path).run
48
- BaseOperation::CreateNewMoFilesStep.new(locales_path).run
45
+ if !parsed_response.nil?
46
+ if !config.disable_gettext
47
+ BaseOperation::SaveNewPoFilesStep.new(target_locales, locales_path, parsed_response).run
48
+ BaseOperation::CreateNewMoFilesStep.new(locales_path).run
49
+ end
50
+
51
+ if !config.disable_yaml
52
+ BaseOperation::SaveNewYamlFilesStep.new(target_locales, yaml_locales_path, parsed_response).run
53
+ BaseOperation::SaveSpecialYamlFilesStep.new(source_locale, target_locales, yaml_locales_path, yaml_file_paths).run
54
+ CleanupYamlFilesStep.new(source_locale, target_locales, yaml_file_paths, yaml_locales_path).run
55
+ info_yaml_directory_structure
56
+ end
49
57
 
50
- info_yaml_directory_structure
51
58
  info_project_url(parsed_response)
52
59
  end
53
60
 
@@ -11,8 +11,10 @@ module TranslationIO
11
11
  def run(params)
12
12
  TranslationIO.info "Updating PO files."
13
13
 
14
+ text_domain = TranslationIO.config.text_domain
15
+
14
16
  @target_locales.each do |target_locale|
15
- po_path = "#{@locales_path}/#{Locale::Tag.parse(target_locale).to_s}/#{TEXT_DOMAIN}.po"
17
+ po_path = "#{@locales_path}/#{Locale::Tag.parse(target_locale).to_s}/#{text_domain}.po"
16
18
  TranslationIO.info po_path, 2, 2
17
19
 
18
20
  if File.exist?(po_path)
@@ -22,15 +22,20 @@ module TranslationIO
22
22
  yaml_locales_path = config.yaml_locales_path
23
23
  yaml_file_paths = config.yaml_file_paths
24
24
 
25
- ApplyYamlSourceEditsStep.new(yaml_file_paths, source_locale).run(params)
25
+ if !config.disable_yaml
26
+ ApplyYamlSourceEditsStep.new(yaml_file_paths, source_locale).run(params)
27
+ end
26
28
 
27
- unless config.disable_gettext
29
+ if !config.disable_gettext
28
30
  BaseOperation::DumpMarkupGettextKeysStep.new(haml_source_files, :haml).run
29
31
  BaseOperation::DumpMarkupGettextKeysStep.new(slim_source_files, :slim).run
30
32
  end
31
33
 
32
34
  UpdatePotFileStep.new(pot_path, source_files + erb_source_files).run(params)
33
- CreateYamlPotFileStep.new(source_locale, yaml_file_paths).run(params)
35
+
36
+ if !config.disable_yaml
37
+ CreateYamlPotFileStep.new(source_locale, yaml_file_paths).run(params)
38
+ end
34
39
 
35
40
  if purge
36
41
  params['purge'] = 'true'
@@ -45,11 +50,16 @@ module TranslationIO
45
50
  uri = URI("#{client.endpoint}/projects/#{client.api_key}/sync")
46
51
  parsed_response = BaseOperation.perform_request(uri, params)
47
52
 
48
- unless parsed_response.nil?
49
- BaseOperation::SaveNewPoFilesStep.new(target_locales, locales_path, parsed_response).run
50
- BaseOperation::CreateNewMoFilesStep.new(locales_path).run
51
- BaseOperation::SaveNewYamlFilesStep.new(target_locales, yaml_locales_path, parsed_response).run
52
- BaseOperation::SaveSpecialYamlFilesStep.new(source_locale, target_locales, yaml_locales_path, yaml_file_paths).run
53
+ if !parsed_response.nil?
54
+ if !config.disable_gettext
55
+ BaseOperation::SaveNewPoFilesStep.new(target_locales, locales_path, parsed_response).run
56
+ BaseOperation::CreateNewMoFilesStep.new(locales_path).run
57
+ end
58
+
59
+ if !config.disable_yaml
60
+ BaseOperation::SaveNewYamlFilesStep.new(target_locales, yaml_locales_path, parsed_response).run
61
+ BaseOperation::SaveSpecialYamlFilesStep.new(source_locale, target_locales, yaml_locales_path, yaml_file_paths).run
62
+ end
53
63
 
54
64
  display_unused_segments(parsed_response, show_purgeable, purge)
55
65
 
@@ -1,24 +1,36 @@
1
1
  module TranslationIO
2
2
  class Config
3
- attr_accessor :api_key, :locales_path, :yaml_locales_path
4
- attr_accessor :source_locale, :target_locales
3
+ attr_accessor :api_key
4
+ attr_accessor :source_locale
5
+ attr_accessor :target_locales
5
6
  attr_accessor :endpoint
7
+ attr_accessor :metadata_path
6
8
  attr_accessor :verbose
7
9
  attr_accessor :test
8
10
 
11
+ attr_accessor :disable_yaml
12
+
13
+ attr_accessor :yaml_locales_path
9
14
  attr_accessor :ignored_key_prefixes
15
+ attr_accessor :localization_key_prefixes
16
+
17
+ attr_accessor :disable_gettext
18
+
19
+ attr_accessor :locales_path
20
+
10
21
  attr_accessor :ignored_source_paths
11
22
  attr_accessor :ignored_source_files
12
23
 
24
+ attr_accessor :parsed_gems
25
+
13
26
  attr_accessor :source_formats
14
27
  attr_accessor :erb_source_formats
15
28
  attr_accessor :haml_source_formats
16
29
  attr_accessor :slim_source_formats
17
30
 
18
- attr_accessor :localization_key_prefixes
19
- attr_accessor :disable_gettext
31
+ attr_accessor :text_domain
32
+ attr_accessor :bound_text_domains
20
33
  attr_accessor :charset
21
- attr_accessor :metadata_path
22
34
 
23
35
  attr_accessor :pot_msgid_bugs_address
24
36
  attr_accessor :pot_package_name
@@ -27,37 +39,72 @@ module TranslationIO
27
39
  attr_accessor :pot_copyright_year
28
40
 
29
41
  def initialize
30
- self.locales_path = File.join('config', 'locales', 'gettext')
31
- self.yaml_locales_path = File.join('config', 'locales')
32
- self.source_locale = :en
33
- self.target_locales = []
34
- self.endpoint = 'https://translation.io/api'
35
- self.verbose = 1
36
- self.test = false
37
-
38
- self.ignored_key_prefixes = []
39
- self.ignored_source_paths = ['vendor/', 'tmp/']
40
- self.ignored_source_files = [] # Files not parsed for GetText entries
41
-
42
- self.source_formats = ['rb', 'ruby', 'rabl']
43
- self.erb_source_formats = ['erb', 'inky']
44
- self.haml_source_formats = ['haml', 'mjmlhaml']
45
- self.slim_source_formats = ['slim', 'mjmlslim']
46
42
 
43
+ #######
44
+ # Global options
45
+ #######
46
+
47
+ self.api_key = ''
48
+ self.source_locale = :en
49
+ self.target_locales = []
50
+ self.endpoint = 'https://translation.io/api'
51
+ self.metadata_path = File.join('config', 'locales', '.translation_io')
52
+ self.verbose = 1
53
+ self.test = false
54
+
55
+ #######
56
+ # YAML options
57
+ #######
58
+
59
+ self.disable_yaml = false
60
+
61
+ # YAML directory
62
+ self.yaml_locales_path = File.join('config', 'locales')
63
+
64
+ # Ignored YAML key prefixes (like 'will_paginate.')
65
+ self.ignored_key_prefixes = []
66
+
67
+ # Cf. https://github.com/translation/rails#custom-localization-key-prefixes
47
68
  self.localization_key_prefixes = []
48
- self.disable_gettext = false
49
- self.charset = 'UTF-8'
50
- self.metadata_path = File.join('config', 'locales', '.translation_io')
51
-
52
- self.pot_msgid_bugs_address = 'contact@translation.io'
53
- self.pot_package_name = File.basename(Dir.pwd)
54
- self.pot_package_version = '1.0'
55
- self.pot_copyright_holder = File.basename(Dir.pwd)
56
- self.pot_copyright_year = Date.today.year
69
+
70
+ #######
71
+ # GetText options
72
+ #######
73
+
74
+ self.disable_gettext = false
75
+
76
+ # GetText directory for PO and MO files
77
+ self.locales_path = File.join('config', 'locales', 'gettext')
78
+
79
+ # These paths and files will not be parsed for GetText entries
80
+ self.ignored_source_paths = ['vendor/', 'tmp/', 'node_modules/', 'logs/', '.git/']
81
+ self.ignored_source_files = []
82
+
83
+ # These gems will be parsed by GetText (use gem names)
84
+ self.parsed_gems = []
85
+
86
+ # Extensions for rb/erb/haml/slim file parsers
87
+ self.source_formats = ['rb', 'ruby', 'rabl']
88
+ self.erb_source_formats = ['erb', 'inky']
89
+ self.haml_source_formats = ['haml', 'mjmlhaml']
90
+ self.slim_source_formats = ['slim', 'mjmlslim']
91
+
92
+ # 'text_domain' will be synced (name of .po/.mo files)
93
+ # 'bound_text_domains' will be read during execution (in that priority order)
94
+ self.text_domain = 'app'
95
+ self.bound_text_domains = ['app']
96
+ self.charset = 'UTF-8'
97
+
98
+ # POT header informations
99
+ self.pot_msgid_bugs_address = 'contact@translation.io'
100
+ self.pot_package_name = File.basename(Dir.pwd)
101
+ self.pot_package_version = '1.0'
102
+ self.pot_copyright_holder = File.basename(Dir.pwd)
103
+ self.pot_copyright_year = Date.today.year
57
104
  end
58
105
 
59
106
  def pot_path
60
- File.join(locales_path, "#{TEXT_DOMAIN}.pot")
107
+ File.join(locales_path, "#{text_domain}.pot")
61
108
  end
62
109
 
63
110
  def yaml_file_paths
@@ -85,6 +132,14 @@ module TranslationIO
85
132
  def source_files_for_formats(formats)
86
133
  file_paths = Dir["**/*.{#{formats.join(',')}}"]
87
134
 
135
+ # Add gems that need to be parsed by GetText
136
+ parsed_gems.each do |gem_name|
137
+ if Gem.loaded_specs[gem_name]
138
+ gem_path = Gem.loaded_specs[gem_name].full_gem_path
139
+ file_paths += Dir["#{gem_path}/**/*.{#{formats.join(',')}}"]
140
+ end
141
+ end
142
+
88
143
  # remove ignored files
89
144
  file_paths = file_paths - ignored_source_files
90
145
 
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.17'
4
+ version: '1.18'
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: 2018-11-12 00:00:00.000000000 Z
12
+ date: 2019-04-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gettext
@@ -35,30 +35,30 @@ dependencies:
35
35
  name: rake
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '12.0'
41
41
  type: :development
42
42
  prerelease: false
43
43
  version_requirements: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '12.0'
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: simplecov
50
50
  requirement: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '0.11'
55
55
  type: :development
56
56
  prerelease: false
57
57
  version_requirements: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '0.11'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: rspec
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +80,9 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '4.1'
83
+ - - "<"
84
+ - !ruby/object:Gem::Version
85
+ version: '7.0'
83
86
  type: :development
84
87
  prerelease: false
85
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -87,6 +90,9 @@ dependencies:
87
90
  - - ">="
88
91
  - !ruby/object:Gem::Version
89
92
  version: '4.1'
93
+ - - "<"
94
+ - !ruby/object:Gem::Version
95
+ version: '7.0'
90
96
  description: Localize your app using either t(".keys") or _("source text") and type
91
97
  "rake translation:sync" to synchronize with your translators on Translation.io.
92
98
  email: contact@translation.io
@@ -143,11 +149,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
149
  - !ruby/object:Gem::Version
144
150
  version: '0'
145
151
  requirements: []
146
- rubyforge_project:
147
- rubygems_version: 2.5.1
152
+ rubygems_version: 3.0.3
148
153
  signing_key:
149
154
  specification_version: 4
150
155
  summary: Localize your app with YAML or GetText. Synchronize with your translators
151
156
  on Translation.io.
152
157
  test_files: []
153
- has_rdoc: false