i18n_generators 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.rdoc +8 -11
- data/Rakefile +8 -0
- data/i18n_generators.gemspec +4 -0
- data/lib/generators/i18n/i18n_generator.rb +2 -2
- data/lib/generators/i18n_translation/i18n_translation_generator.rb +69 -41
- data/lib/generators/i18n_translation/lib/yaml.rb +4 -4
- data/lib/i18n_generators/version.rb +1 -1
- data/spec/i18n_locale_command_spec.rb +34 -26
- data/spec/i18n_translation_command_spec.rb +6 -10
- data/spec/spec_helper.rb +6 -1
- data/spec/translator_spec.rb +11 -18
- data/spec/yaml_spec.rb +5 -4
- metadata +49 -35
- data/generators/i18n/USAGE +0 -11
- data/generators/i18n/i18n_generator.rb +0 -88
- data/generators/i18n/lib/yaml.rb +0 -187
- data/generators/i18n/templates/base.yml +0 -0
- data/generators/i18n/templates/i18n_config.rb +0 -4
- data/generators/i18n/templates/translation.yml +0 -1
- data/generators/i18n_locale/USAGE +0 -10
- data/generators/i18n_locale/i18n_locale_command.rb +0 -141
- data/generators/i18n_locale/i18n_locale_generator.rb +0 -8
- data/generators/i18n_locale/lib/cldr.rb +0 -138
- data/generators/i18n_scaffold/i18n_scaffold_generator.rb +0 -2
- data/generators/i18n_scaffold/templates/controller.rb +0 -85
- data/generators/i18n_scaffold/templates/functional_test.rb +0 -45
- data/generators/i18n_scaffold/templates/helper.rb +0 -2
- data/generators/i18n_scaffold/templates/helper_test.rb +0 -4
- data/generators/i18n_scaffold/templates/layout.html.erb +0 -17
- data/generators/i18n_scaffold/templates/style.css +0 -54
- data/generators/i18n_scaffold/templates/view_edit.html.erb +0 -18
- data/generators/i18n_scaffold/templates/view_index.html.erb +0 -24
- data/generators/i18n_scaffold/templates/view_new.html.erb +0 -17
- data/generators/i18n_scaffold/templates/view_show.html.erb +0 -10
- data/generators/i18n_translation/USAGE +0 -8
- data/generators/i18n_translation/i18n_translation_command.rb +0 -124
- data/generators/i18n_translation/i18n_translation_generator.rb +0 -8
- data/generators/i18n_translation/lib/erb_executer.rb +0 -30
- data/generators/i18n_translation/lib/recording_backend.rb +0 -15
- data/generators/i18n_translation/lib/through_ryoku.rb +0 -7
- data/generators/i18n_translation/lib/translator.rb +0 -27
- data/spec/cldr_spec.rb +0 -54
@@ -1,17 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
-
|
4
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
-
<head>
|
6
|
-
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
7
|
-
<title><%= controller_class_name %>: <%%= controller.action_name %></title>
|
8
|
-
<%%= stylesheet_link_tag 'scaffold' %>
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
|
12
|
-
<p style="color: green"><%%= flash[:notice] %></p>
|
13
|
-
|
14
|
-
<%%= yield %>
|
15
|
-
|
16
|
-
</body>
|
17
|
-
</html>
|
@@ -1,54 +0,0 @@
|
|
1
|
-
body { background-color: #fff; color: #333; }
|
2
|
-
|
3
|
-
body, p, ol, ul, td {
|
4
|
-
font-family: verdana, arial, helvetica, sans-serif;
|
5
|
-
font-size: 13px;
|
6
|
-
line-height: 18px;
|
7
|
-
}
|
8
|
-
|
9
|
-
pre {
|
10
|
-
background-color: #eee;
|
11
|
-
padding: 10px;
|
12
|
-
font-size: 11px;
|
13
|
-
}
|
14
|
-
|
15
|
-
a { color: #000; }
|
16
|
-
a:visited { color: #666; }
|
17
|
-
a:hover { color: #fff; background-color:#000; }
|
18
|
-
|
19
|
-
.fieldWithErrors {
|
20
|
-
padding: 2px;
|
21
|
-
background-color: red;
|
22
|
-
display: table;
|
23
|
-
}
|
24
|
-
|
25
|
-
#errorExplanation {
|
26
|
-
width: 400px;
|
27
|
-
border: 2px solid red;
|
28
|
-
padding: 7px;
|
29
|
-
padding-bottom: 12px;
|
30
|
-
margin-bottom: 20px;
|
31
|
-
background-color: #f0f0f0;
|
32
|
-
}
|
33
|
-
|
34
|
-
#errorExplanation h2 {
|
35
|
-
text-align: left;
|
36
|
-
font-weight: bold;
|
37
|
-
padding: 5px 5px 5px 15px;
|
38
|
-
font-size: 12px;
|
39
|
-
margin: -7px;
|
40
|
-
background-color: #c00;
|
41
|
-
color: #fff;
|
42
|
-
}
|
43
|
-
|
44
|
-
#errorExplanation p {
|
45
|
-
color: #333;
|
46
|
-
margin-bottom: 0;
|
47
|
-
padding: 5px;
|
48
|
-
}
|
49
|
-
|
50
|
-
#errorExplanation ul li {
|
51
|
-
font-size: 12px;
|
52
|
-
list-style: square;
|
53
|
-
}
|
54
|
-
|
@@ -1,18 +0,0 @@
|
|
1
|
-
<h1><%% translate(:editing, :default => "Editing %{model}", :model => <%= class_name %>.human_name, :scope => [:railties, :scaffold]) %></h1>
|
2
|
-
|
3
|
-
<%% form_for(@<%= singular_name %>) do |f| %>
|
4
|
-
<%%= f.error_messages %>
|
5
|
-
|
6
|
-
<% for attribute in attributes -%>
|
7
|
-
<p>
|
8
|
-
<%%= f.label :<%= attribute.name %> %><br />
|
9
|
-
<%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
|
10
|
-
</p>
|
11
|
-
<% end -%>
|
12
|
-
<p>
|
13
|
-
<%%= f.submit translate(:update, :default => "Update", :scope => [:railties, :scaffold]) %>
|
14
|
-
</p>
|
15
|
-
<%% end %>
|
16
|
-
|
17
|
-
<%%= link_to translate(:show, :default => 'Show', :scope => [:railties, :scaffold]), @<%= singular_name %> %> |
|
18
|
-
<%%= link_to translate(:back, :default => 'Back', :scope => [:railties, :scaffold]), <%= plural_name %>_path %>
|
@@ -1,24 +0,0 @@
|
|
1
|
-
<h1><%%= translate(:listing, :default => "Listing %{model}", :model => <%= class_name %>.human_name(:count => @<%= plural_name %>.size), :count => @<%= plural_name %>.size, :scope => [:railties, :scaffold]) %></h1>
|
2
|
-
|
3
|
-
<table>
|
4
|
-
<tr>
|
5
|
-
<% for attribute in attributes -%>
|
6
|
-
<th><%%= <%= class_name %>.human_attribute_name('<%= attribute.column.name %>') %></th>
|
7
|
-
<% end -%>
|
8
|
-
</tr>
|
9
|
-
|
10
|
-
<%% for <%= singular_name %> in @<%= plural_name %> %>
|
11
|
-
<tr>
|
12
|
-
<% for attribute in attributes -%>
|
13
|
-
<td><%%=h <%= singular_name %>.<%= attribute.name %> %></td>
|
14
|
-
<% end -%>
|
15
|
-
<td><%%= link_to translate(:show, :default => 'Show', :scope => [:railties, :scaffold]), <%= singular_name %> %></td>
|
16
|
-
<td><%%= link_to translate(:edit, :default => 'Edit', :scope => [:railties, :scaffold]), edit_<%= singular_name %>_path(<%= singular_name %>) %></td>
|
17
|
-
<td><%%= link_to translate(:destroy, :default => 'Destroy', :scope => [:railties, :scaffold]), <%= singular_name %>, :confirm => translate(:confirmation, :default => 'Are you sure?', :scope => [:railties, :scaffold]), :method => :delete %></td>
|
18
|
-
</tr>
|
19
|
-
<%% end %>
|
20
|
-
</table>
|
21
|
-
|
22
|
-
<br />
|
23
|
-
|
24
|
-
<%%= link_to translate(:new, :default => "New {{model}}", :model => <%= class_name %>.human_name, :scope => [:railties, :scaffold]), new_<%= singular_name %>_path %>
|
@@ -1,17 +0,0 @@
|
|
1
|
-
<h1><%%= translate(:new, :default => "New %{model}", :model => <%= class_name %>.human_name, :scope => [:railties, :scaffold]) %></h1>
|
2
|
-
|
3
|
-
<%% form_for(@<%= singular_name %>) do |f| %>
|
4
|
-
<%%= f.error_messages %>
|
5
|
-
|
6
|
-
<% for attribute in attributes -%>
|
7
|
-
<p>
|
8
|
-
<%%= f.label :<%= attribute.name %> %><br />
|
9
|
-
<%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
|
10
|
-
</p>
|
11
|
-
<% end -%>
|
12
|
-
<p>
|
13
|
-
<%%= f.submit translate(:create, :default => "Create", :scope => [:railties, :scaffold]) %>
|
14
|
-
</p>
|
15
|
-
<%% end %>
|
16
|
-
|
17
|
-
<%%= link_to translate(:back, :default => 'Back', :scope => [:railties, :scaffold]), <%= plural_name %>_path %>
|
@@ -1,10 +0,0 @@
|
|
1
|
-
<% for attribute in attributes -%>
|
2
|
-
<p>
|
3
|
-
<b><%%= <%= class_name %>.human_attribute_name('<%= attribute.column.name %>') %>:</b>
|
4
|
-
<%%=h @<%= singular_name %>.<%= attribute.name %> %>
|
5
|
-
</p>
|
6
|
-
|
7
|
-
<% end -%>
|
8
|
-
|
9
|
-
<%%= link_to translate(:edit, :default => 'Edit', :scope => [:railties, :scaffold]), edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
|
10
|
-
<%%= link_to translate(:back, :default => 'Back', :scope => [:railties, :scaffold]), <%= plural_name %>_path %>
|
@@ -1,124 +0,0 @@
|
|
1
|
-
require 'rails_generator'
|
2
|
-
require 'rails_generator/commands'
|
3
|
-
require File.join(File.dirname(__FILE__), 'lib/translator')
|
4
|
-
require File.join(File.dirname(__FILE__), 'lib/recording_backend')
|
5
|
-
require File.join(File.dirname(__FILE__), 'lib/erb_executer')
|
6
|
-
require File.join(File.dirname(__FILE__), '../i18n/lib/yaml')
|
7
|
-
include I18nTranslationGeneratorModule
|
8
|
-
|
9
|
-
module I18nGenerator::Generator
|
10
|
-
module Commands #:nodoc:
|
11
|
-
module Create
|
12
|
-
def translation_yaml
|
13
|
-
I18n.locale = locale_name
|
14
|
-
models = model_filenames.map do |model_name|
|
15
|
-
model = begin
|
16
|
-
m = begin
|
17
|
-
model_name.camelize.constantize
|
18
|
-
rescue LoadError
|
19
|
-
end
|
20
|
-
next if m.nil? || !m.table_exists? || !m.respond_to?(:content_columns)
|
21
|
-
m.class_eval %Q[def self.english_name; "#{model_name}"; end]
|
22
|
-
m
|
23
|
-
rescue
|
24
|
-
next
|
25
|
-
end
|
26
|
-
end.compact
|
27
|
-
translation_keys = []
|
28
|
-
translation_keys += models.map {|m| "activerecord.models.#{m.english_name}"}
|
29
|
-
models.each do |model|
|
30
|
-
cols = model.content_columns + model.reflect_on_all_associations
|
31
|
-
cols.delete_if {|c| %w[created_at updated_at].include? c.name} unless self.include_timestamps
|
32
|
-
translation_keys += cols.map {|c| "activerecord.attributes.#{model.english_name}.#{c.name}"}
|
33
|
-
end
|
34
|
-
logger.debug "#{models.size} models found."
|
35
|
-
|
36
|
-
# pick all translated keywords from view files
|
37
|
-
original_backend = I18n.backend.dup
|
38
|
-
I18n.backend = RecordingBackend.new
|
39
|
-
|
40
|
-
Dir["#{RAILS_ROOT}/app/views/**/*.erb"].each do |f|
|
41
|
-
ErbExecuter.new.exec_erb f
|
42
|
-
end
|
43
|
-
logger.debug "#{I18n.backend.keys.size} translation keys found in views."
|
44
|
-
(translation_keys += I18n.backend.keys).uniq!
|
45
|
-
I18n.backend = original_backend
|
46
|
-
|
47
|
-
if translation_keys.blank?
|
48
|
-
logger.info "No translation keys found. Skipped generating translation_#{locale_name}.yml file."
|
49
|
-
else
|
50
|
-
# translate all keys and generate the YAML file
|
51
|
-
now = Time.now
|
52
|
-
translations = translate_all(translation_keys)
|
53
|
-
logger.debug "took #{Time.now - now} secs to translate."
|
54
|
-
|
55
|
-
yaml = generate_yaml(locale_name, translations).to_s(true)
|
56
|
-
template 'i18n:translation.yml', "config/locales/translation_#{locale_name}.yml", :assigns => {:locale_name => locale_name, :translations => yaml}
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
private
|
61
|
-
def model_filenames
|
62
|
-
Dir.chdir("#{RAILS_ROOT}/app/models/") do
|
63
|
-
Dir["**/*.rb"].map {|m| m.sub(/\.rb$/, '')}
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# mixin translations into existing yaml file
|
68
|
-
def generate_yaml(locale_name, translations)
|
69
|
-
yaml = YamlDocument.new("config/locales/translation_#{locale_name}.yml", locale_name)
|
70
|
-
each_value [], translations do |parents, value|
|
71
|
-
node = parents.inject(yaml[locale_name]) {|node, parent| node[parent]}
|
72
|
-
if value.is_a? String
|
73
|
-
node.value = value
|
74
|
-
else
|
75
|
-
value.each {|key, val| node[key].value = val}
|
76
|
-
end
|
77
|
-
end
|
78
|
-
yaml
|
79
|
-
end
|
80
|
-
|
81
|
-
# receives an array of keys and returns :key => :translation hash
|
82
|
-
def translate_all(keys)
|
83
|
-
returning ActiveSupport::OrderedHash.new do |oh|
|
84
|
-
# fix the order first(for multi thread translating)
|
85
|
-
keys.each do |key|
|
86
|
-
if key.to_s.include? '.'
|
87
|
-
key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
|
88
|
-
key_prefix.inject(oh) {|h, k| h[k] ||= ActiveSupport::OrderedHash.new}[key_suffix] = nil
|
89
|
-
else
|
90
|
-
oh[key] = nil
|
91
|
-
end
|
92
|
-
end
|
93
|
-
threads = []
|
94
|
-
keys.each do |key|
|
95
|
-
threads << Thread.new do
|
96
|
-
logger.debug "translating #{key} ..."
|
97
|
-
Thread.pass
|
98
|
-
if key.to_s.include? '.'
|
99
|
-
key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
|
100
|
-
existing_translation = I18n.backend.send(:lookup, locale_name, key_suffix, key_prefix)
|
101
|
-
key_prefix.inject(oh) {|h, k| h[k]}[key_suffix] = existing_translation ? existing_translation : translator.translate(key_suffix)
|
102
|
-
else
|
103
|
-
existing_translation = I18n.backend.send(:lookup, locale_name, key)
|
104
|
-
oh[key] = existing_translation ? existing_translation : translator.translate(key)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
threads.each {|t| t.join}
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# iterate through all values
|
113
|
-
def each_value(parents, src, &block)
|
114
|
-
src.each do |k, v|
|
115
|
-
if v.is_a?(ActiveSupport::OrderedHash)
|
116
|
-
each_value parents + [k], v, &block
|
117
|
-
else
|
118
|
-
yield parents + [k], v
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require "#{File.dirname(__FILE__)}/through_ryoku"
|
2
|
-
|
3
|
-
module I18nTranslationGeneratorModule
|
4
|
-
class ErbExecuter
|
5
|
-
def exec_erb(filename)
|
6
|
-
begin
|
7
|
-
# ERB.new(File.read(f)).result
|
8
|
-
(m = Module.new).module_eval <<-EOS
|
9
|
-
class Executer
|
10
|
-
extend ERB::DefMethod
|
11
|
-
include ActionView::Helpers::TranslationHelper
|
12
|
-
include I18nTranslationGeneratorModule::ThroughRyoku
|
13
|
-
|
14
|
-
fname = '#{filename}'
|
15
|
-
erb = nil
|
16
|
-
File.open(fname) {|f| erb = ERB.new(f.read, nil, '-') }
|
17
|
-
erb.def_method(self, 'execute', fname)
|
18
|
-
end
|
19
|
-
EOS
|
20
|
-
nil.class_eval {def method_missing(method, *args, &block); nil; end}
|
21
|
-
m.const_get('Executer').new.execute { }
|
22
|
-
rescue => e
|
23
|
-
p e
|
24
|
-
# do nothing
|
25
|
-
ensure
|
26
|
-
nil.class_eval {undef :method_missing} if nil.respond_to? :method_missing
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module I18nTranslationGeneratorModule
|
2
|
-
class RecordingBackend
|
3
|
-
attr_reader :keys
|
4
|
-
|
5
|
-
def initialize
|
6
|
-
@keys = []
|
7
|
-
end
|
8
|
-
|
9
|
-
def translate(locale, key, options = {})
|
10
|
-
# @keys << key.to_sym
|
11
|
-
@keys << (Array(options[:scope]) + [key]).flatten.join('.')
|
12
|
-
end
|
13
|
-
alias :t :translate
|
14
|
-
end
|
15
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'json' if RUBY_VERSION >= '1.9'
|
3
|
-
|
4
|
-
module I18nTranslationGeneratorModule
|
5
|
-
class Translator
|
6
|
-
def initialize(lang)
|
7
|
-
@lang, @cache = lang, {}
|
8
|
-
end
|
9
|
-
|
10
|
-
def translate(word)
|
11
|
-
return @cache[word] if @cache[word]
|
12
|
-
begin
|
13
|
-
w = CGI.escape ActiveSupport::Inflector.humanize(word)
|
14
|
-
json = OpenURI.open_uri("http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=#{w}&langpair=en%7C#{@lang}").read
|
15
|
-
result = if RUBY_VERSION >= '1.9'
|
16
|
-
::JSON.parse json
|
17
|
-
else
|
18
|
-
ActiveSupport::JSON.decode(json)
|
19
|
-
end
|
20
|
-
result['responseStatus'] == 200 ? (@cache[word] = result['responseData']['translatedText']) : word
|
21
|
-
rescue => e
|
22
|
-
puts %Q[failed to translate "#{word}" into "#{@lang}" language.]
|
23
|
-
word
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/spec/cldr_spec.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
$KCODE = 'U'
|
3
|
-
|
4
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
5
|
-
require File.join(File.dirname(__FILE__), '../generators/i18n_locale/lib/cldr')
|
6
|
-
include I18nLocaleGeneratorModule
|
7
|
-
|
8
|
-
describe CldrDocument do
|
9
|
-
before do
|
10
|
-
OpenURI.stub!(:open_uri).and_return(File.open(File.join(File.dirname(__FILE__), 'data/cldr/ja.html')))
|
11
|
-
@cldr = CldrDocument.new 'ja-JP'
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'fetches date/formats/default value' do
|
15
|
-
@cldr.lookup('date/formats/default').should == '%Y/%m/%d'
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'fetches date/formats/short value' do
|
19
|
-
@cldr.lookup('date/formats/short').should == '%y/%m/%d'
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'fetches date/formats/long value' do
|
23
|
-
@cldr.lookup('date/formats/long').should == '%Y年%m月%d日%A'
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'fetches date/day_names value' do
|
27
|
-
@cldr.lookup('date/day_names').should == ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日']
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'fetches date/abbr_day_names value' do
|
31
|
-
@cldr.lookup('date/abbr_day_names').should == ['日', '月', '火', '水', '木', '金', '土']
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'fetches time/formats/default value' do
|
35
|
-
@cldr.lookup('time/formats/default').should == '%Y/%m/%d %H:%M:%S'
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'fetches time/formats/short value' do
|
39
|
-
@cldr.lookup('time/formats/short').should == '%y/%m/%d %H:%M'
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'fetches time/formats/long value' do
|
43
|
-
@cldr.lookup('time/formats/long').should == '%Y年%m月%d日%A %H時%M分%S秒%Z'
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'fetches time/am value' do
|
47
|
-
@cldr.lookup('time/am').should == '午前'
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'fetches time/pm value' do
|
51
|
-
@cldr.lookup('time/pm').should == '午後'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|