amatsuda-i18n_generators 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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
+