i18n_translator 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +59 -0
- data/lib/i18n_translator.rake +21 -0
- data/lib/i18n_translator.rb +62 -0
- data/lib/i18n_translator/version.rb +3 -0
- data/test/test_i18n_translator.rb +53 -0
- metadata +99 -0
data/README.rdoc
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
== Overview
|
2
|
+
|
3
|
+
Rake task which creates translated locales files of a rails project from source locales.
|
4
|
+
Translations are 'bulk' translations from google, and might be reviewed but that's a easy first step.
|
5
|
+
Create your locales files with your own language and run the task with targeted languages.
|
6
|
+
It uses the gem 'easy_translator' which use google translations api.
|
7
|
+
|
8
|
+
== Usage
|
9
|
+
|
10
|
+
rake i18n:translate['en','fr;es'].
|
11
|
+
|
12
|
+
Separate targets languages symbols with semicolons.
|
13
|
+
<b>/!\ Don't put space after the coma for rake tasks parameters.</b>
|
14
|
+
|
15
|
+
With no additional argument, it will translate and create locales for <b>all</b> your source locales.
|
16
|
+
If you want to just do the work with only one locale source, pass an additional path to file source argument to rake tasks :
|
17
|
+
|
18
|
+
rake i18n:translate['en','fr;es','config/locales/user/en.yml'].
|
19
|
+
|
20
|
+
== Convention
|
21
|
+
|
22
|
+
The source locale is supposed to be named <lang>.yml where lang is the language symbol (fr, en , es ... and so on)
|
23
|
+
|
24
|
+
== Example
|
25
|
+
|
26
|
+
- config
|
27
|
+
- locales
|
28
|
+
- models
|
29
|
+
- user
|
30
|
+
- en.yml
|
31
|
+
- book
|
32
|
+
- en.yml
|
33
|
+
|
34
|
+
Will generate :
|
35
|
+
|
36
|
+
- config
|
37
|
+
- locales
|
38
|
+
- models
|
39
|
+
- user
|
40
|
+
- en.yml
|
41
|
+
- fr.yml
|
42
|
+
- es.yml
|
43
|
+
- book
|
44
|
+
- en.yml
|
45
|
+
- fr.yml
|
46
|
+
- es.yml
|
47
|
+
|
48
|
+
== Dependencies
|
49
|
+
|
50
|
+
* rake
|
51
|
+
* easy_translator
|
52
|
+
|
53
|
+
== TO-DOs
|
54
|
+
|
55
|
+
Add options to be more flexible ; ie pass a translator lambda to use other translator.
|
56
|
+
|
57
|
+
== Issues
|
58
|
+
|
59
|
+
Sometimes phrases with interpolations are not double quoted
|
@@ -0,0 +1,21 @@
|
|
1
|
+
namespace :i18n do
|
2
|
+
|
3
|
+
def indicator
|
4
|
+
Proc.new do |dirname, lang|
|
5
|
+
print "\033[37m --> #{dirname} : #{lang} .. \033[32m done \n"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Translate and create locales from source locale"
|
10
|
+
|
11
|
+
task :translate, [:from, :to, :path_to_file] => :environment do |t , args|
|
12
|
+
locales = args[:path_to_file] || Dir.glob("#{RAILS_ROOT}/config/locales/**/*.yml")
|
13
|
+
|
14
|
+
|
15
|
+
locales.each do |locale_path|
|
16
|
+
dirname = File.dirname(locale_path)
|
17
|
+
I18nTranslator.create_locales(:dir_path => dirname, :from => args[:from], :to => args[:to].split(';'), :indicator => indicator)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'yaml/encoding'
|
3
|
+
require 'yaml'
|
4
|
+
require 'easy_translate'
|
5
|
+
|
6
|
+
class Insider
|
7
|
+
|
8
|
+
def self.redefine klass, method, &block
|
9
|
+
klass.send(:alias_method, original_method(method), method)
|
10
|
+
klass.send(:define_method, method) do |*params|
|
11
|
+
instance_exec(*params, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.undefine klass, method
|
16
|
+
klass.send(:undef_method, method)
|
17
|
+
klass.send(:alias_method, method, original_method(method))
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.original_method method
|
21
|
+
('original_' + method.to_s).to_sym
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
module I18nTranslator
|
27
|
+
|
28
|
+
def self.create_locales(args)
|
29
|
+
redefine_hash_to_yaml
|
30
|
+
source = File.join(args[:dir_path], "#{args[:from].to_s}.yml")
|
31
|
+
source_yaml = YAML.load_file(source)
|
32
|
+
|
33
|
+
args[:to].each do |language|
|
34
|
+
@@target_language = language
|
35
|
+
target_yaml = source_yaml.dup.replace(language.to_s => source_yaml[args[:from].to_s])
|
36
|
+
target = File.join(args[:dir_path], "#{language.to_s}.yml")
|
37
|
+
|
38
|
+
File.open(target, 'w+') do |file|
|
39
|
+
file << YAML.unescape(YAML.dump(target_yaml))
|
40
|
+
end
|
41
|
+
args[:indicator].call(args[:dir_path], language) if args[:indicator]
|
42
|
+
end
|
43
|
+
|
44
|
+
Insider.undefine(Hash, :to_yaml)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.redefine_hash_to_yaml
|
48
|
+
Insider.redefine(Hash, :to_yaml) do |opts|
|
49
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
50
|
+
out.map( taguri, to_yaml_style ) do |map|
|
51
|
+
sort.each do |k, v|
|
52
|
+
v = EasyTranslate.translate(v, :to => @@target_language) unless v.is_a?(Hash)
|
53
|
+
map.add( k, v )
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
import File.join(File.dirname(__FILE__), 'i18n_translator.rake')
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'i18n_translator'
|
3
|
+
require 'mocha'
|
4
|
+
|
5
|
+
$KCODE = 'utf-8'
|
6
|
+
|
7
|
+
class TestI18nTranslator < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
stubs_easy_translate
|
11
|
+
|
12
|
+
@dirname = File.join(File.dirname(__FILE__), 'config/locales/models/user')
|
13
|
+
@source = File.join(@dirname, 'fr.yml')
|
14
|
+
@targets = {:en => File.join(@dirname, 'en.yml'), :es => File.join(@dirname, 'es.yml')}
|
15
|
+
I18nTranslator.create_locales(:dir_path => @dirname, :from => :fr, :to => [:en, :es])
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
File.delete(*@targets.values)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_should_create_english_locale_for_model_user
|
23
|
+
yaml_locale = YAML.load_file(@targets[:en])
|
24
|
+
|
25
|
+
assert_equal 'car', yaml_locale['en']['models']['user']['car']
|
26
|
+
assert_equal 'error', yaml_locale['en']['models']['user']['error']
|
27
|
+
assert_equal 'home', yaml_locale['en']['models']['user']['house']
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_should_create_spanish_locale_for_model_user
|
31
|
+
yaml_locale = YAML.load_file(@targets[:es])
|
32
|
+
|
33
|
+
assert_equal 'coche', yaml_locale['es']['models']['user']['car']
|
34
|
+
assert_equal 'error', yaml_locale['es']['models']['user']['error']
|
35
|
+
assert_equal 'casa', yaml_locale['es']['models']['user']['house']
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_keep_double_quoted_interpolations
|
39
|
+
yaml_locale = YAML.load_file(@targets[:en])
|
40
|
+
|
41
|
+
assert_equal 'Users : {{n}}', yaml_locale['en']['models']['user']['total_user']
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def stubs_easy_translate
|
47
|
+
fr_to_en = [['maison', "home"], ['erreur', 'error'], ['voiture', 'car'], ['Utilisateurs : {{n}}', 'Users : {{n}}']]
|
48
|
+
fr_to_es = [['maison', "casa"], ['erreur', 'error'], ['voiture', 'coche'], ['Utilisateurs : {{n}}', 'Usuario : {{n}}']]
|
49
|
+
map = {:en => fr_to_en, :es => fr_to_es}
|
50
|
+
map.each {|target, translations| translations.each { |fr, translated| EasyTranslate.stubs(:translate).with(fr, :to => target).returns(translated) } }
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: i18n_translator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Philippe Cantin
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-03-15 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rake
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: easy_translate
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
description: " Automatically create translated locales files of a rails project from source locales. \n Translations are 'bulk' translations from google, and might be reviewed but that's a easy first step'.\n Create your locales files with your own language and run the task with targettd languages.\n Example: > rake i18n:translate['en','fr;es']. See more on github\n "
|
50
|
+
email:
|
51
|
+
- anoiaque@gmail.com
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files:
|
57
|
+
- README.rdoc
|
58
|
+
files:
|
59
|
+
- lib/i18n_translator/version.rb
|
60
|
+
- lib/i18n_translator.rb
|
61
|
+
- lib/i18n_translator.rake
|
62
|
+
- README.rdoc
|
63
|
+
- test/test_i18n_translator.rb
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: https://github.com/anoiaque/i18n_translator
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project: i18n_translator
|
94
|
+
rubygems_version: 1.3.7
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: Automatically create translated locales files of a rails project
|
98
|
+
test_files:
|
99
|
+
- test/test_i18n_translator.rb
|