amatsuda-i18n_generators 0.0.5

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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,56 @@
1
+ I18n generator
2
+ ======
3
+
4
+ This plugin generates a config file and locale files for Rails 2.2 i18n feature.
5
+
6
+
7
+ Installation
8
+ =======
9
+
10
+ As a gem
11
+
12
+ % sudo gem install amatsuda-i18n_generators -s http://gems.github.com
13
+
14
+ As a Rails plugin
15
+
16
+ % ./script/plugin install git://github.com/amatsuda/i18n_generators.git
17
+
18
+
19
+ Example
20
+ =======
21
+
22
+ % ./script/generate i18n ja-JP (de-AT, pt-BR, etc.)
23
+
24
+ This will generate following files.
25
+
26
+ config/initializers/i18n_config.rb
27
+ lib/locale/action_view_ja-JP.yml
28
+ lib/locale/active_record_ja-JP.yml
29
+ lib/locale/active_support_ja-JP.yml
30
+
31
+
32
+ Requirement
33
+ =======
34
+
35
+ This plugin requires gettext gem ( http://rubyforge.org/projects/gettext/ )
36
+ and sufficient speed of the Internet connection.
37
+
38
+
39
+ Caution
40
+ =======
41
+
42
+ Current version of this plugin is very very very very roughly implemented just for experiment.
43
+ Every time you execute the generate command, the plugin connects to the Unicode CLDR website and scrapes the huge amount of its contents.
44
+ Please be careful not to harm your network environment and CLDR website by running this plugin too many times.
45
+
46
+
47
+ Todo
48
+ =======
49
+
50
+ * More accurate format tranlation.
51
+ * Download the XML data file via CLDR website and store in tmp directory.
52
+ * Merging with the existing locale file.
53
+ * Currency sign
54
+
55
+
56
+ Copyright (c) 2008 Akira Matsuda, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the i18n_generator plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the i18n_generator plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'I18nGenerator'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
@@ -0,0 +1,13 @@
1
+ Description:
2
+ Generates a config file and locale files and a model/attributes translation file for Rails i18n feature.
3
+
4
+ Example:
5
+ ./script/generate i18n locale_name (ja-JP, de-AT, etc.)
6
+
7
+ This will create:
8
+ config/initializers/i18n_config.rb
9
+ lib/locale/action_view_ja-JP.yml
10
+ lib/locale/active_record_ja-JP.yml
11
+ lib/locale/active_support_ja-JP.yml
12
+ lib/locale/models_ja-JP.yml
13
+
@@ -0,0 +1,41 @@
1
+ require 'rails_generator'
2
+ require 'rails_generator/commands'
3
+ require 'rubygems'
4
+ require 'gettext'
5
+
6
+ class I18nGenerator < Rails::Generator::NamedBase
7
+ attr_reader :locale_name, :cldr, :generate_models_only, :generate_locales_only
8
+
9
+ def initialize(runtime_args, runtime_options = {})
10
+ super
11
+ unless name =~ /[a-zA-Z]{2}[-_][a-zA-Z]{2}/
12
+ puts 'ERROR: Wrong locale format. Please input in ??-?? format.'
13
+ exit
14
+ end
15
+ @locale_name = "#{name[0..1].downcase}-#{name[3..4].upcase}"
16
+ GetText.bindtextdomain 'rails'
17
+ GetText.locale = @locale_name
18
+
19
+ @cldr = CldrDocument.new @locale_name
20
+ end
21
+
22
+ def manifest
23
+ record do |m|
24
+ m.directory 'lib/locale'
25
+ unless self.generate_models_only
26
+ m.template 'i18n:i18n_config.rb', 'config/initializers/i18n_config.rb', :assigns => {:locale_name => @locale_name}
27
+ m.active_support_yaml
28
+ m.active_record_yaml
29
+ m.action_view_yaml
30
+ end
31
+ unless self.generate_locales_only
32
+ m.models_yaml
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ require File.join(File.dirname(__FILE__), '../i18n_locales/i18n_locales_command')
39
+ require File.join(File.dirname(__FILE__), '../i18n_models/i18n_models_command')
40
+ Rails::Generator::Commands::Create.send :include, I18nGenerator::Generator::Commands::Create
41
+
File without changes
@@ -0,0 +1,5 @@
1
+ I18n.load_path += Dir.glob("#{RAILS_ROOT}/lib/locale/*.yml")
2
+
3
+ I18n.default_locale = '<%= locale_name %>'
4
+ I18n.locale = '<%= locale_name %>'
5
+
@@ -0,0 +1,16 @@
1
+ <%= locale_name %>:
2
+ activerecord:
3
+ models:
4
+ <% models.each do |model| -%>
5
+ <%= "#{model.english_name}: #{model.translated_name}" %>
6
+ <% end -%>
7
+ attributes:
8
+ <% models.each do |model| -%>
9
+ <%= "#{model.english_name}:" %>
10
+ <% model.content_columns.each do |col| -%>
11
+ <% unless %w[created_at updated_at].include?(col.name) -%>
12
+ <%= "#{col.name}: #{col.translated_name}" %>
13
+ <% end -%>
14
+ <% end -%>
15
+ <% end -%>
16
+
@@ -0,0 +1,12 @@
1
+ Description:
2
+ Generates a config file and locale files for Rails i18n feature.
3
+
4
+ Example:
5
+ ./script/generate i18n locale_name (ja-JP, de-AT, etc.)
6
+
7
+ This will create:
8
+ config/initializers/i18n_config.rb
9
+ lib/locale/action_view_ja-JP.yml
10
+ lib/locale/active_record_ja-JP.yml
11
+ lib/locale/active_support_ja-JP.yml
12
+
@@ -0,0 +1,91 @@
1
+ require 'rails_generator'
2
+ require 'rails_generator/commands'
3
+ require 'rubygems'
4
+ require 'gettext'
5
+ require File.join(File.dirname(__FILE__), 'lib/yaml')
6
+ require File.join(File.dirname(__FILE__), 'lib/cldr')
7
+ include I18nLocalesGeneratorModule
8
+
9
+ module I18nGenerator::Generator
10
+ module Commands #:nodoc:
11
+ module Create
12
+ def active_support_yaml
13
+ open_yaml('active_support') do |yaml|
14
+ yaml[locale_name].descendant_nodes do |node|
15
+ v = cldr.lookup(node.path)
16
+ node.value = v if !v.nil? && !(v.is_a?(Array) && v.any? {|e| e.nil?})
17
+ end
18
+ end
19
+ end
20
+
21
+ def active_record_yaml
22
+ open_yaml('active_record') do |yaml|
23
+ yaml[locale_name]['activerecord']['errors']['messages'].children.each do |node|
24
+ unless node.value.nil?
25
+ node.value = transfer_format('%{fn} ' + node.value.gsub('{{count}}', '%d')) do |v|
26
+ GetText._(v)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ def action_view_yaml
34
+ open_yaml('action_view') do |yaml|
35
+ yaml[locale_name]['datetime']['distance_in_words'].children.each do |node|
36
+ if !node.value.nil?
37
+ node.value = GetText._(node.value)
38
+ elsif ((children = node.children).size == 2) && (children.map(&:key) == %w[one other])
39
+ children['one'].value, children['other'].value = translate_one_and_other(children.map(&:value))
40
+ end
41
+ end
42
+ yaml[locale_name]['activerecord']['errors']['template'].children.each do |node|
43
+ if !node.value.nil?
44
+ node.value = if node.value == 'There were problems with the following fields:'
45
+ GetText.n_('There was a problem with the following field:', node.value, 2)
46
+ else
47
+ GetText._(node.value)
48
+ end
49
+ elsif ((children = node.children).size == 2) && (children.map(&:key) == %w[one other])
50
+ children['one'].value, children['other'].value = if children['one'].value == '1 error prohibited this {{model}} from being saved'
51
+ translate_one_and_other(['%{num} error prohibited this {{model}} from being saved', children['other']])
52
+ else
53
+ translate_one_and_other(children.map(&:value))
54
+ end
55
+ end
56
+ end
57
+ yaml[locale_name]['number'].descendant_nodes do |node|
58
+ v = cldr.lookup(node.path)
59
+ node.value = v if !v.nil? && !(v.is_a?(Array) && v.any? {|e| e.nil?})
60
+ end
61
+ end
62
+ end
63
+
64
+ private
65
+ def open_yaml(filename_base)
66
+ original_yml = I18n.load_path.detect {|lp| lp =~ /\/lib\/#{filename_base}\/locale\/en-US\.yml$/}
67
+ doc = YamlDocument.new(original_yml, locale_name)
68
+ yield doc
69
+ file('i18n:base.yml', "lib/locale/#{filename_base}_#{locale_name}.yml") do |f|
70
+ doc.to_s
71
+ end
72
+ end
73
+
74
+ def transfer_format(args)
75
+ vals = if args.is_a?(Array)
76
+ args.map {|v| v.gsub('{{count}}', '%d').gsub('{{model}}', '%{record}')}
77
+ else
78
+ args.gsub('{{count}}', '%d').gsub('{{model}}', '%{record}')
79
+ end
80
+ result = yield vals
81
+ result.gsub(/^%\{fn\}/, '').gsub('%d', '{{count}}').gsub('%{record}', '{{model}}').gsub('%{num}', '{{count}}').strip
82
+ end
83
+
84
+ def translate_one_and_other(values)
85
+ values = values.map {|v| v.is_a?(Node) ? v.value : v}
86
+ [transfer_format(values) {|v| GetText.n_(v.first, v.second, 1)}, transfer_format(values) {|v| GetText.n_(v.first, v.second, 2)}]
87
+ end
88
+ end
89
+ end
90
+ end
91
+
@@ -0,0 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), '../i18n/i18n_generator')
2
+
3
+ class I18nLocalesGenerator < I18nGenerator
4
+ def initialize(runtime_args, runtime_options = {})
5
+ super
6
+ @generate_locales_only = true
7
+ end
8
+ end
9
+
@@ -0,0 +1,125 @@
1
+ $KCODE = 'U'
2
+
3
+ require 'open-uri'
4
+
5
+ module I18nLocalesGeneratorModule
6
+ class CldrDocument
7
+ def initialize(locale_name)
8
+ @locale_name = locale_name
9
+ @summaries = [load_cldr_data(locale_name.tr('-', '_')), load_cldr_data(locale_name.sub(/-.*/, ''))]
10
+ end
11
+
12
+ def lookup(path)
13
+ case path.sub(/^\/#{@locale_name}\//, '')
14
+ when 'date/formats/default'
15
+ convert_date_pattern search('calendar-gregorian', 'pattern', 'date-medium')
16
+ when 'date/formats/short'
17
+ convert_date_pattern search('calendar-gregorian', 'pattern', 'date-short')
18
+ when 'date/formats/long'
19
+ convert_date_pattern search('calendar-gregorian', 'pattern', 'date-full')
20
+ when 'date/day_names'
21
+ [search('calendar-gregorian', 'day', 'sunday:format-wide'),
22
+ search('calendar-gregorian', 'day', 'monday:format-wide'),
23
+ search('calendar-gregorian', 'day', 'tuesday:format-wide'),
24
+ search('calendar-gregorian', 'day', 'wednesday:format-wide'),
25
+ search('calendar-gregorian', 'day', 'thursday:format-wide'),
26
+ search('calendar-gregorian', 'day', 'friday:format-wide'),
27
+ search('calendar-gregorian', 'day', 'saturday:format-wide')]
28
+ when 'date/abbr_day_names'
29
+ [search('calendar-gregorian', 'day', 'sunday:format-abbreviated'),
30
+ search('calendar-gregorian', 'day', 'monday:format-abbreviated'),
31
+ search('calendar-gregorian', 'day', 'tuesday:format-abbreviated'),
32
+ search('calendar-gregorian', 'day', 'wednesday:format-abbreviated'),
33
+ search('calendar-gregorian', 'day', 'thursday:format-abbreviated'),
34
+ search('calendar-gregorian', 'day', 'friday:format-abbreviated'),
35
+ search('calendar-gregorian', 'day', 'saturday:format-abbreviated')]
36
+ when 'date/month_names'
37
+ ['~',
38
+ search('calendar-gregorian', 'month', '[01]-format-wide'),
39
+ search('calendar-gregorian', 'month', '[02]-format-wide'),
40
+ search('calendar-gregorian', 'month', '[03]-format-wide'),
41
+ search('calendar-gregorian', 'month', '[04]-format-wide'),
42
+ search('calendar-gregorian', 'month', '[05]-format-wide'),
43
+ search('calendar-gregorian', 'month', '[06]-format-wide'),
44
+ search('calendar-gregorian', 'month', '[07]-format-wide'),
45
+ search('calendar-gregorian', 'month', '[08]-format-wide'),
46
+ search('calendar-gregorian', 'month', '[09]-format-wide'),
47
+ search('calendar-gregorian', 'month', '[10]-format-wide'),
48
+ search('calendar-gregorian', 'month', '[11]-format-wide'),
49
+ search('calendar-gregorian', 'month', '[12]-format-wide')]
50
+ when 'date/abbr_month_names'
51
+ ['~',
52
+ search('calendar-gregorian', 'month', '[01]-format-abbreviated'),
53
+ search('calendar-gregorian', 'month', '[02]-format-abbreviated'),
54
+ search('calendar-gregorian', 'month', '[03]-format-abbreviated'),
55
+ search('calendar-gregorian', 'month', '[04]-format-abbreviated'),
56
+ search('calendar-gregorian', 'month', '[05]-format-abbreviated'),
57
+ search('calendar-gregorian', 'month', '[06]-format-abbreviated'),
58
+ search('calendar-gregorian', 'month', '[07]-format-abbreviated'),
59
+ search('calendar-gregorian', 'month', '[08]-format-abbreviated'),
60
+ search('calendar-gregorian', 'month', '[09]-format-abbreviated'),
61
+ search('calendar-gregorian', 'month', '[10]-format-abbreviated'),
62
+ search('calendar-gregorian', 'month', '[11]-format-abbreviated'),
63
+ search('calendar-gregorian', 'month', '[12]-format-abbreviated')]
64
+ # when 'date/order'
65
+ when 'time/formats/default'
66
+ format = search('calendar-gregorian', 'pattern', 'date+time')
67
+ date = convert_date_pattern search('calendar-gregorian', 'pattern', 'date-medium')
68
+ time = convert_date_pattern search('calendar-gregorian', 'pattern', 'time-medium')
69
+ (format.nil? || date.nil? || time.nil?) ? nil : format.sub('{0}', time).sub('{1}', date)
70
+ when 'time/formats/short'
71
+ format = search('calendar-gregorian', 'pattern', 'date+time')
72
+ date = convert_date_pattern search('calendar-gregorian', 'pattern', 'date-short')
73
+ time = convert_date_pattern search('calendar-gregorian', 'pattern', 'time-short')
74
+ (format.nil? || date.nil? || time.nil?) ? nil : format.sub('{0}', time).sub('{1}', date)
75
+ when 'time/formats/long'
76
+ format = search('calendar-gregorian', 'pattern', 'date+time')
77
+ date = convert_date_pattern search('calendar-gregorian', 'pattern', 'date-full')
78
+ time = convert_date_pattern search('calendar-gregorian', 'pattern', 'time-full')
79
+ (format.nil? || date.nil? || time.nil?) ? nil : format.sub('{0}', time).sub('{1}', date)
80
+ when 'time/am'
81
+ search('calendar-gregorian', 'day-period', 'am')
82
+ when 'time/pm'
83
+ search('calendar-gregorian', 'day-period', 'pm')
84
+ # action_view
85
+ when 'number/format/separator'
86
+ search('number', 'symbol', 'decimal')
87
+ when 'number/format/separator'
88
+ search('number', 'symbol', 'group')
89
+ when 'number/currency/format/format'
90
+ format = search('number', 'currency', 'name-pattern/​other')
91
+ format.nil? ? nil : format.tr(' ', '').sub('{0}', '%u').sub('{1}', '%n')
92
+ else
93
+ nil
94
+ end
95
+ end
96
+
97
+ private
98
+ def load_cldr_data(locale_name)
99
+ cldr = begin
100
+ OpenURI.open_uri("http://www.unicode.org/cldr/data/charts/summary/#{locale_name}.html").read
101
+ rescue
102
+ puts "WARNING: Couldn't find locale data for #{locale_name} on the web."
103
+ ''
104
+ end
105
+ cldr.split("\n").grep(/^<tr>/).delete_if {|r| r =~ /^<tr><td>\d*<\/td><td class='[gn]'>names<\/td>/}
106
+ end
107
+
108
+ def search(n1, n2, g)
109
+ pattern = Regexp.new /<tr><td>\d*<\/td><td class='[ng]'>#{Regexp.quote(n1)}<\/td><td class='[ng]'>#{Regexp.quote(n2)}<\/td><td class='[ng]'>#{Regexp.quote(g)}<\/td>/
110
+ extract_pattern = /<td class='v'>(?:<span.*?>)?(.*?)(?:<\/span>)?<\/td><td>/
111
+ _, value = *extract_pattern.match(@summaries[0].grep(pattern).first)
112
+ return value unless value.nil?
113
+ _, value = *extract_pattern.match(@summaries[1].grep(pattern).first)
114
+ value
115
+ end
116
+
117
+ def convert_date_pattern(val)
118
+ return val if val.nil?
119
+ val = val.sub('MMMM', '%B').sub('MMM', '%b')
120
+ val = val.sub('yyyy', '%Y').sub('yy', '%y').sub('MM', '%m').sub('M', '%m').sub(/dd|d/, '%d')
121
+ val.sub('EEEEE', '%a').sub('EEEE', '%A').sub('H', '%H').sub('mm', '%M').sub('ss', '%S').sub('v', '%Z')
122
+ end
123
+ end
124
+ end
125
+
@@ -0,0 +1,141 @@
1
+ require 'yaml'
2
+
3
+ module I18nLocalesGeneratorModule
4
+ class YamlDocument
5
+ def initialize(yml_path, locale_name)
6
+ @locale_name, @nodes = locale_name, []
7
+ File.read(yml_path).each_with_index do |line_text, i|
8
+ n = Node.new(self, i, line_text.chomp)
9
+ @nodes << (n.key == 'en-US' ? Node.new(self, i, "#{locale_name}:") : n)
10
+ end
11
+ end
12
+
13
+ def next
14
+ @current_line += 1
15
+ return false if @current_line == @nodes.size
16
+ @nodes[@current_line].is_blank_or_comment? ? self.next : @nodes[@current_line]
17
+ end
18
+
19
+ def prev
20
+ return false if @current_line == 0
21
+ @current_line -= 1
22
+ @nodes[@current_line].is_blank_or_comment? ? self.prev : @nodes[@current_line]
23
+ end
24
+
25
+ def parent_of(child)
26
+ @current_line = child.line
27
+ while n = self.prev
28
+ return n if n.indent_level == child.indent_level - 2
29
+ end
30
+ self
31
+ end
32
+
33
+ def children_of(parent)
34
+ nodes = Nodes.new
35
+ @current_line = parent.line
36
+ while n = self.next
37
+ if n.indent_level < parent.indent_level + 2
38
+ break
39
+ elsif n.indent_level == parent.indent_level + 2
40
+ nodes << n
41
+ end
42
+ end
43
+ nodes
44
+ end
45
+
46
+ def [](node_name)
47
+ @current_line = @nodes.detect {|n| (n.indent_level == 0) && (n.key == node_name)}.line
48
+ @nodes[@current_line]
49
+ end
50
+
51
+ def document
52
+ self
53
+ end
54
+
55
+ def path
56
+ ''
57
+ end
58
+
59
+ def to_s
60
+ @nodes.inject('') do |ret, n|
61
+ ret << n.text + "\n"
62
+ end
63
+ end
64
+ end
65
+
66
+ class Node
67
+ attr_reader :line, :indent_level
68
+
69
+ def initialize(doc, line_index, text)
70
+ @doc, @line, @text = doc, line_index, text
71
+ @text =~ /(^\s*)/
72
+ @indent_level = $1.nil? ? 0 : $1.size
73
+ @yaml = YAML.load(@text + ' ')
74
+ end
75
+
76
+ def parent
77
+ @parent ||= @doc.parent_of self
78
+ end
79
+
80
+ def children
81
+ @children ||= @doc.children_of(self)
82
+ end
83
+
84
+ def [](node_name)
85
+ children.detect {|c| c.key == node_name}
86
+ end
87
+
88
+ def key
89
+ @yaml.is_a?(Hash) ? @yaml.keys.first : nil
90
+ end
91
+
92
+ def value
93
+ @yaml.is_a?(Hash) ? @yaml.values.first : nil
94
+ end
95
+
96
+ def value=(val)
97
+ if @yaml[self.key] != val
98
+ @yaml[self.key] = val
99
+ @changed = true
100
+ end
101
+ end
102
+
103
+ def text
104
+ if @changed
105
+ v = if self.value.is_a?(Array)
106
+ "[#{self.value * ', '}]"
107
+ else
108
+ %Q["#{self.value}"]
109
+ end
110
+ "#{' ' * self.indent_level}#{self.key}: #{v}"
111
+ else
112
+ @text
113
+ end
114
+ end
115
+
116
+ def changed?
117
+ @changed
118
+ end
119
+
120
+ def is_blank_or_comment?
121
+ @text.sub(/#.*$/, '').gsub(/\s/, '').empty?
122
+ end
123
+
124
+ def path
125
+ @path ||= "#{self.parent.path}/#{self.key}"
126
+ end
127
+
128
+ def descendant_nodes(&block)
129
+ yield self if self.value
130
+ self.children.each {|child| child.descendant_nodes(&block)} if self.children
131
+ end
132
+ end
133
+
134
+ class Nodes < Array
135
+ def[](index)
136
+ return detect {|node| node.key == index} if index.is_a?(String)
137
+ super
138
+ end
139
+ end
140
+ end
141
+
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Generates a model/attributes translation file for Rails i18n feature.
3
+
4
+ Example:
5
+ ./script/generate i18n locale_name (ja-JP, de-AT, etc.)
6
+
7
+ This will create:
8
+ lib/locale/models_ja-JP.yml
9
+
@@ -0,0 +1,48 @@
1
+ require 'rails_generator'
2
+ require 'rails_generator/commands'
3
+ require File.join(File.dirname(__FILE__), 'lib/translator')
4
+ include I18nModelsGeneratorModule
5
+
6
+ module I18nGenerator::Generator
7
+ module Commands #:nodoc:
8
+ module Create
9
+ def models_yaml
10
+ models = Dir.chdir("#{RAILS_ROOT}/app/models/") do
11
+ Dir["**/*.rb"].map {|m| m.sub(/\.rb$/, '').capitalize.constantize}
12
+ end
13
+ I18n.locale = locale_name
14
+ lang = locale_name.sub(/-.*$/, '')
15
+ models.each do |model|
16
+ model_name = model.class_name.underscore
17
+ registered_t_name = I18n.t("activerecord.models.#{model_name}", :default => model_name)
18
+
19
+ model.class_eval <<-END
20
+ def self.english_name
21
+ "#{model_name}"
22
+ end
23
+
24
+ def self.translated_name
25
+ "#{registered_t_name != model_name ? registered_t_name : Translator.translate(model_name, lang)}"
26
+ end
27
+ END
28
+ model.content_columns.each do |col|
29
+ next if %w[created_at updated_at].include? col.name
30
+ registered_t_name = I18n.t("activerecord.attributes.#{model_name}.#{col.name}", :default => col.name)
31
+ col.class_eval <<-END
32
+ def translated_name
33
+ "#{registered_t_name != col.name ? registered_t_name : Translator.translate(col.name, lang)}"
34
+ end
35
+ END
36
+ end
37
+ end
38
+ generate_yaml(locale_name, models)
39
+ end
40
+
41
+ private
42
+ def generate_yaml(locale_name, models)
43
+ template 'i18n:models.yml', "lib/locale/models_#{locale_name}.yml", :assigns => {:locale_name => locale_name, :models => models}
44
+ end
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), '../i18n/i18n_generator')
2
+
3
+ class I18nModelsGenerator < I18nGenerator
4
+ def initialize(runtime_args, runtime_options = {})
5
+ super
6
+ @generate_models_only = true
7
+ end
8
+ end
9
+
@@ -0,0 +1,21 @@
1
+ require 'open-uri'
2
+
3
+ module I18nModelsGeneratorModule
4
+ class Translator
5
+ #TODO
6
+ def self.translatable?(lang)
7
+ end
8
+
9
+ def self.translate(word, lang)
10
+ begin
11
+ json = OpenURI.open_uri("http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=#{word}&langpair=en%7C#{lang}").read
12
+ result = ActiveSupport::JSON.decode(json)
13
+ return result['responseData']['translatedText'] if result['responseStatus'] == 200
14
+ rescue e
15
+ puts %Q[failed to translate "#{word}" into "#{lang}" language.]
16
+ word
17
+ end
18
+ end
19
+ end
20
+ end
21
+