babelphish 0.1.7 → 0.2.0
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/README.rdoc +31 -3
- data/bin/babelphish +11 -7
- data/lib/babelphish.rb +3 -1
- data/lib/babelphish/translator.rb +3 -126
- data/lib/tasks/babelphish.rake +10 -2
- data/test/test_babelphish.rb +0 -26
- data/test/test_html_translator.rb +22 -0
- data/test/test_yml_translator.rb +31 -0
- metadata +4 -2
data/README.rdoc
CHANGED
@@ -14,15 +14,43 @@ Translate the en.yml file into all supported languages:
|
|
14
14
|
Translate the en.yml file into all supported languages and overwrite other yml files:
|
15
15
|
babelphish -y ./my/locales/en.yml -o
|
16
16
|
|
17
|
-
|
17
|
+
=== Using in your application
|
18
|
+
Babelphish can be used to translate content programmatically within your application. Use it thus:
|
19
|
+
|
20
|
+
Translate content into a single language:
|
21
|
+
from = 'en'
|
22
|
+
to = 'es'
|
23
|
+
translation = Babelphish::Translator.translate('hello world', to, from)
|
18
24
|
|
19
|
-
|
25
|
+
Translate content into all supported languages at once. This will return a hash table with the locale as keys (ie 'en', 'es', etc).
|
26
|
+
translations = Babelphish::Translator.multiple_translate('hello world', Babelphish::GoogleTranslate::LANGUAGES, self.locale)
|
27
|
+
|
28
|
+
Here's a more extensive example
|
29
|
+
# Translate title and body using Google
|
30
|
+
def translate()
|
31
|
+
translate_from_locale = 'en'
|
32
|
+
title_translations = Babelphish::Translator.multiple_translate(self.title, Babelphish::GoogleTranslate::LANGUAGES, translate_from_locale)
|
33
|
+
body_translations = Babelphish::Translator.multiple_translate(self.body, Babelphish::GoogleTranslate::LANGUAGES, translate_from_locale)
|
34
|
+
|
35
|
+
Babelphish::GoogleTranslate::LANGUAGES.each do |language|
|
36
|
+
self.content_translations.create!(:title => title_translations[language],
|
37
|
+
:body => body_translations[language],
|
38
|
+
:locale => language)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
20
42
|
|
21
|
-
|
43
|
+
== INSTALL:
|
44
|
+
|
45
|
+
ya2yaml should be automatically installed when you install babelphish, but is isn't:
|
22
46
|
|
23
47
|
* sudo gem install ya2yaml
|
24
48
|
* sudo gem install babelphish
|
25
49
|
|
50
|
+
== Related Blog Posts
|
51
|
+
http://www.justinball.com/2009/05/19/babelphish-yml-translation-made-simple/comment-page-1/
|
52
|
+
|
53
|
+
|
26
54
|
== LICENSE:
|
27
55
|
|
28
56
|
(The MIT License)
|
data/bin/babelphish
CHANGED
@@ -6,14 +6,18 @@ require 'babelphish'
|
|
6
6
|
task = :babelphish
|
7
7
|
|
8
8
|
OptionParser.new do |opts|
|
9
|
-
opts.banner = "Usage: babelphish [options]"
|
10
|
-
opts.on('-y', '--yaml yml', "
|
9
|
+
opts.banner = "Usage: babelphish [options] "
|
10
|
+
opts.on('-y', '--yaml yml', "Path to the yml file to be translated") { |yml| ENV['yml'] = yml }
|
11
|
+
opts.on('-h', '--html html', "Path to the directory containing erb files to be translated") { |html| ENV['html'] = html }
|
12
|
+
opts.on('-l', '--language language', "Required if using 'html' option. This specifies the source language for the html or erb files") { |language| ENV['language'] = language }
|
11
13
|
opts.on('-o', '--overwrite', "Overwrite existing translations(default 'false')") { ENV['overwrite'] = 'yes' }
|
12
14
|
opts.on('-t', '--translate_to to', "Only translate from the source file to a specific language (ie -t es will only translate to Spanish)") { |to| ENV['translate_to'] = to }
|
13
15
|
end.parse!
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
Babelphish.load_tasks
|
18
|
+
|
19
|
+
# if Babelphish.load_tasks
|
20
|
+
# Rake::Task[task].invoke
|
21
|
+
# else
|
22
|
+
# STDERR.puts "Can't find Rakefile. Are we in a Rails folder?"
|
23
|
+
# end
|
data/lib/babelphish.rb
CHANGED
@@ -29,11 +29,13 @@ end
|
|
29
29
|
require File.dirname(__FILE__) + '/../lib/babelphish/translator'
|
30
30
|
require File.dirname(__FILE__) + '/../lib/babelphish/languages'
|
31
31
|
require File.dirname(__FILE__) + '/../lib/babelphish/exceptions'
|
32
|
+
require File.dirname(__FILE__) + '/../lib/babelphish/yml_translator'
|
33
|
+
require File.dirname(__FILE__) + '/../lib/babelphish/html_translator'
|
32
34
|
|
33
35
|
$KCODE = 'UTF8'
|
34
36
|
|
35
37
|
module Babelphish
|
36
|
-
VERSION = '0.
|
38
|
+
VERSION = '0.2.0'
|
37
39
|
GOOGLE_AJAX_URL = "http://ajax.googleapis.com/ajax/services/language/"
|
38
40
|
MAX_RETRIES = 3
|
39
41
|
|
@@ -2,128 +2,9 @@ module Babelphish
|
|
2
2
|
module Translator
|
3
3
|
|
4
4
|
class << self
|
5
|
-
|
6
|
-
def translate_yaml(yml, overwrite = false, translate_to = nil)
|
7
|
-
@yml = yml
|
8
|
-
language = File.basename(yml, ".yml")
|
9
|
-
if !Babelphish::GoogleTranslate::LANGUAGES.include?(language)
|
10
|
-
STDERR.puts "#{language} is not one of the available languages. Please choose a standard localized yml file. i.e. en.yml."
|
11
|
-
return
|
12
|
-
end
|
13
|
-
if translate_to
|
14
|
-
puts "Translating #{language} to #{translate_to}"
|
15
|
-
translate_and_write_yml(yml, translate_to, language, overwrite)
|
16
|
-
puts "Finished translating #{language} to #{translate_to}"
|
17
|
-
else
|
18
|
-
# Babelphish::GoogleTranslate::LANGUAGES.each do |to|
|
19
|
-
# puts "Translating #{language} to #{to}"
|
20
|
-
# translate_and_write_yml(yml, to, language, overwrite)
|
21
|
-
# puts "Finished translating #{language} to #{to}"
|
22
|
-
# end
|
23
|
-
tos = Babelphish::GoogleTranslate::LANGUAGES
|
24
|
-
translate_and_write_many_yml(yml, tos, language, overwrite)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def translate_and_write_many_yml(yml, tos, from, overwrite)
|
29
|
-
return unless File.exist?(yml)
|
30
|
-
source = YAML.load_file(yml)
|
31
|
-
translated_source = YAML.load_file(yml)
|
32
|
-
translate_many_keys(translated_source, tos, from)
|
33
|
-
# At this point translated_source contains a translation for every language. Cut it apart into individual hashes
|
34
|
-
tos.each do |to|
|
35
|
-
next if to == from # don't want to overwrite the source file
|
36
|
-
extracted_translation = {}
|
37
|
-
extract_translation(source, translated_source, extracted_translation, to)
|
38
|
-
# change the top level key from the source language to the destination language
|
39
|
-
translated_filename = File.join(File.dirname(yml), "#{to}.yml")
|
40
|
-
return if File.exist?(translated_filename) && !overwrite
|
41
|
-
extracted_translation[to] = extracted_translation[from]
|
42
|
-
extracted_translation.delete(from)
|
43
|
-
File.open(translated_filename, 'w') { |f| f.write(extracted_translation.ya2yaml) }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def extract_translation(source, translated_source, extracted, language)
|
48
|
-
source.each_key do |key|
|
49
|
-
if source[key].is_a?(Hash)
|
50
|
-
extracted[key] = {}
|
51
|
-
extract_translation(source[key], translated_source[key], extracted[key], language)
|
52
|
-
else
|
53
|
-
extracted[key] = translated_source[key][language]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def translate_many_keys(translate_hash, tos, from)
|
59
|
-
translate_hash.each_key do |key|
|
60
|
-
if translate_hash[key].is_a?(Hash)
|
61
|
-
translate_many_keys(translate_hash[key], tos, from)
|
62
|
-
else
|
63
|
-
if key == false
|
64
|
-
puts "Key #{key} was evaluated as false. Check your yml file and be sure it does not include values like no: No"
|
65
|
-
elsif key == true
|
66
|
-
puts "Key #{key} was evaluated as true. Check your yml file and be sure it does not include values like yes: Yes"
|
67
|
-
elsif !translate_hash[key].nil?
|
68
|
-
# pull out all the string substitutions so that google doesn't translate those
|
69
|
-
pattern = /\{\{.+\}\}/
|
70
|
-
holder = '{{---}}'
|
71
|
-
replacements = translate_hash[key].scan(pattern)
|
72
|
-
translate_hash[key].gsub!(pattern, holder)
|
73
|
-
translations = multiple_translate(translate_hash[key], tos, from)
|
74
|
-
translations.each_key do |locale|
|
75
|
-
replacements.each do |r|
|
76
|
-
translations[locale].sub!(holder, r)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
translate_hash[key] = translations
|
80
|
-
else
|
81
|
-
puts "Key #{key} contains no data"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def translate_and_write_yml(yml, to, from, overwrite)
|
88
|
-
return if to == from
|
89
|
-
return unless File.exist?(yml)
|
90
|
-
translated_filename = File.join(File.dirname(yml), "#{to}.yml")
|
91
|
-
return if File.exist?(translated_filename) && !overwrite
|
92
|
-
source = YAML.load_file(yml)
|
93
|
-
translate_keys(source, to, from)
|
94
|
-
# change the top level key from the source language to the destination language
|
95
|
-
source[to] = source[from]
|
96
|
-
source.delete(from)
|
97
|
-
File.open(translated_filename, 'w') { |f| f.write(source.ya2yaml) }
|
98
|
-
end
|
99
|
-
|
100
|
-
def translate_keys(translate_hash, to, from)
|
101
|
-
translate_hash.each_key do |key|
|
102
|
-
if translate_hash[key].is_a?(Hash)
|
103
|
-
translate_keys(translate_hash[key], to, from)
|
104
|
-
else
|
105
|
-
if key == false
|
106
|
-
puts "Key #{key} was evaluated as false. Check your yml file and be sure to escape values like no with 'no'. ie 'no': 'No'"
|
107
|
-
elsif key == true
|
108
|
-
puts "Key #{key} was evaluated as true. Check your yml file and be sure to escape values like yes with 'yes'. ie 'yes': 'Yes'"
|
109
|
-
elsif !translate_hash[key].nil?
|
110
|
-
# pull out all the string substitutions so that google doesn't translate those
|
111
|
-
pattern = /\{\{.+\}\}/
|
112
|
-
holder = '{{---}}'
|
113
|
-
replacements = translate_hash[key].scan(pattern)
|
114
|
-
translate_hash[key].gsub!(pattern, holder)
|
115
|
-
translate_hash[key] = translate(translate_hash[key], to, from)
|
116
|
-
replacements.each do |r|
|
117
|
-
translate_hash[key].sub!(holder, r)
|
118
|
-
end
|
119
|
-
else
|
120
|
-
puts "Key #{key} contains no data"
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
5
|
|
126
6
|
# from: http://ruby.geraldbauer.ca/google-translation-api.html
|
7
|
+
# translate text from 'from' to 'to'
|
127
8
|
def translate(text, to, from = 'en', tries = 0)
|
128
9
|
|
129
10
|
return if to == from
|
@@ -145,16 +26,12 @@ module Babelphish
|
|
145
26
|
# Try again a few more times
|
146
27
|
translate(text, to, from, tries+=1)
|
147
28
|
else
|
148
|
-
|
149
|
-
puts "#{json['responseDetails']} "
|
150
|
-
puts "To retry only this translation try: 'babelphish -o -y #{@yml} -t #{to}' to retry the translation. Response: #{response}" if defined?(@yml)
|
151
|
-
raise Exceptions::GoogleResponseError, "#{json['responseDetails']}"
|
29
|
+
raise Exceptions::GoogleResponseError, "A problem occured while translating from #{from} to #{to}. #{json['responseDetails']}"
|
152
30
|
end
|
153
31
|
end
|
154
32
|
end
|
155
33
|
|
156
34
|
# translate from the 'from' language into all available languages
|
157
|
-
|
158
35
|
# multiple strings and multiple languages
|
159
36
|
#
|
160
37
|
# http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=hello%20world&langpair=en|it&q=goodbye&langpair=en|fr
|
@@ -198,7 +75,7 @@ module Babelphish
|
|
198
75
|
# Try again a few more times
|
199
76
|
multiple_translate(text, tos, from, tries+=1)
|
200
77
|
else
|
201
|
-
|
78
|
+
raise Exceptions::GoogleResponseError, "A problem occured while translating. #{response}"
|
202
79
|
end
|
203
80
|
end
|
204
81
|
end
|
data/lib/tasks/babelphish.rake
CHANGED
@@ -3,13 +3,21 @@ task :babelphish do
|
|
3
3
|
require 'babelphish/translator'
|
4
4
|
options={}
|
5
5
|
yml = ENV['yml']
|
6
|
+
html = ENV['html']
|
7
|
+
language = ENV['language']
|
6
8
|
overwrite = ENV['overwrite'] == 'yes'
|
7
9
|
translate_to = ENV['translate_to'] || nil
|
8
10
|
|
9
11
|
if yml
|
10
|
-
Babelphish::
|
12
|
+
Babelphish::YmlTranslator.translate(yml, overwrite, translate_to)
|
13
|
+
elsif html
|
14
|
+
if language.blank?
|
15
|
+
STDERR.puts "No source language specified when using 'html' option. Defaulting to 'en'"
|
16
|
+
language = 'en'
|
17
|
+
end
|
18
|
+
Babelphish::HtmlTranslator.translate(html, Babelphish::GoogleTranslate::LANGUAGES, language, overwrite)
|
11
19
|
else
|
12
|
-
STDERR.puts "Please specify the directory where your files live. i.e. babelphish -
|
20
|
+
STDERR.puts "Please specify the directory where your files live. i.e. babelphish -y ./my/locales or babelphish -h ./some/directory/with/erb_or_html/files"
|
13
21
|
end
|
14
22
|
|
15
23
|
end
|
data/test/test_babelphish.rb
CHANGED
@@ -36,30 +36,4 @@ class TestBabelphish < Test::Unit::TestCase
|
|
36
36
|
assert_equal Babelphish::Translator.supported_languages, Babelphish::GoogleTranslate::LANGUAGES
|
37
37
|
end
|
38
38
|
|
39
|
-
def test_single_yml_translation
|
40
|
-
overwrite = true
|
41
|
-
translate_to = 'es'
|
42
|
-
yml = File.join(File.dirname(__FILE__), 'translations', 'en.yml')
|
43
|
-
Babelphish::Translator.translate_yaml(yml, overwrite, translate_to)
|
44
|
-
translated_yml = File.join(File.dirname(__FILE__), 'translations', "#{translate_to}.yml")
|
45
|
-
translation = YAML.load_file(translated_yml)
|
46
|
-
assert translation['es']
|
47
|
-
assert translation['es']['babelphish']
|
48
|
-
assert_equal "Este es un nivel más bajo", translation['es']['babelphish']['more']['test_more']
|
49
|
-
assert_equal "Esto es una prueba de cadenas", translation['es']['babelphish']['test']
|
50
|
-
assert_equal "Esta es una cadena con la incorporación {{insert}}", translation['es']['babelphish']['test_embedded']
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_multiple_yml_translation
|
54
|
-
overwrite = true
|
55
|
-
yml = File.join(File.dirname(__FILE__), 'translations', 'en.yml')
|
56
|
-
Babelphish::Translator.translate_yaml(yml, overwrite)
|
57
|
-
Babelphish::GoogleTranslate::LANGUAGES.each do |to|
|
58
|
-
translated_yml = File.join(File.dirname(__FILE__), 'translations', "#{to}.yml")
|
59
|
-
translation = YAML.load_file(translated_yml)
|
60
|
-
assert translation[to]
|
61
|
-
assert translation[to]['babelphish']['test_embedded'].include?("{{insert}}")
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
39
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestHtmlTranslator < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_html_translation
|
6
|
+
overwrite = true
|
7
|
+
translate_from = 'en'
|
8
|
+
directory = File.join(File.dirname(__FILE__), 'html_translations')
|
9
|
+
Babelphish::HtmlTranslator.translate(directory, Babelphish::GoogleTranslate::LANGUAGES, translate_from, overwrite)
|
10
|
+
Babelphish::GoogleTranslate::LANGUAGES.each do |to|
|
11
|
+
if to != translate_from
|
12
|
+
# This will make sure the file was created
|
13
|
+
translated_html = File.join(File.dirname(__FILE__), 'html_translations', "test.#{to}.html.erb")
|
14
|
+
text = IO.read(translated_html)
|
15
|
+
# Make sure the translation didn't remove code
|
16
|
+
assert text.include?("<%= 'Some ruby code' %>")
|
17
|
+
assert text.include?('<%= "test something else #{variable}" %>')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestYmlTranslator < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_single_yml_translation
|
6
|
+
overwrite = true
|
7
|
+
translate_to = 'es'
|
8
|
+
yml = File.join(File.dirname(__FILE__), 'translations', 'en.yml')
|
9
|
+
Babelphish::YmlTranslator.translate(yml, overwrite, translate_to)
|
10
|
+
translated_yml = File.join(File.dirname(__FILE__), 'translations', "#{translate_to}.yml")
|
11
|
+
translation = YAML.load_file(translated_yml)
|
12
|
+
assert translation['es']
|
13
|
+
assert translation['es']['babelphish']
|
14
|
+
assert_equal "Este es un nivel más bajo", translation['es']['babelphish']['more']['test_more']
|
15
|
+
assert_equal "Esto es una prueba de cadenas", translation['es']['babelphish']['test']
|
16
|
+
assert_equal "Esta es una cadena con la incorporación {{insert}}", translation['es']['babelphish']['test_embedded']
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_multiple_yml_translation
|
20
|
+
overwrite = true
|
21
|
+
yml = File.join(File.dirname(__FILE__), 'translations', 'en.yml')
|
22
|
+
Babelphish::YmlTranslator.translate(yml, overwrite)
|
23
|
+
Babelphish::GoogleTranslate::LANGUAGES.each do |to|
|
24
|
+
translated_yml = File.join(File.dirname(__FILE__), 'translations', "#{to}.yml")
|
25
|
+
translation = YAML.load_file(translated_yml)
|
26
|
+
assert translation[to]
|
27
|
+
assert translation[to]['babelphish']['test_embedded'].include?("{{insert}}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: babelphish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Ball
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-13 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -102,3 +102,5 @@ summary: Translate with Google like a fule => 'fool'
|
|
102
102
|
test_files:
|
103
103
|
- test/test_babelphish.rb
|
104
104
|
- test/test_helper.rb
|
105
|
+
- test/test_html_translator.rb
|
106
|
+
- test/test_yml_translator.rb
|