i18n_generators 0.8.1 → 1.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -1
- data/README.rdoc +20 -56
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/generators/i18n/USAGE +0 -1
- data/generators/i18n/i18n_generator.rb +0 -1
- data/generators/i18n/templates/i18n_config.rb +0 -1
- data/generators/i18n/templates/translation.yml +1 -1
- data/generators/i18n_locale/USAGE +0 -1
- data/generators/i18n_locale/i18n_locale_command.rb +0 -1
- data/generators/i18n_locale/i18n_locale_generator.rb +0 -1
- data/generators/i18n_locale/lib/cldr.rb +0 -1
- data/generators/i18n_scaffold/i18n_scaffold_generator.rb +0 -1
- data/generators/i18n_scaffold/templates/controller.rb +2 -2
- data/generators/i18n_scaffold/templates/view_edit.html.erb +1 -1
- data/generators/i18n_scaffold/templates/view_index.html.erb +1 -1
- data/generators/i18n_scaffold/templates/view_new.html.erb +1 -1
- data/generators/i18n_translation/USAGE +0 -1
- data/generators/i18n_translation/i18n_translation_command.rb +0 -1
- data/generators/i18n_translation/i18n_translation_generator.rb +0 -1
- data/generators/i18n_translation/lib/erb_executer.rb +0 -1
- data/generators/i18n_translation/lib/recording_backend.rb +0 -1
- data/generators/i18n_translation/lib/through_ryoku.rb +0 -1
- data/generators/i18n_translation/lib/translator.rb +0 -1
- data/i18n_generators.gemspec +16 -5
- data/lib/generators/i18n/USAGE +12 -0
- data/lib/generators/i18n/i18n_generator.rb +17 -0
- data/lib/generators/i18n_locale/USAGE +10 -0
- data/lib/generators/i18n_locale/i18n_locale_generator.rb +46 -0
- data/lib/generators/i18n_translation/USAGE +8 -0
- data/lib/generators/i18n_translation/i18n_translation_generator.rb +111 -0
- data/lib/generators/i18n_translation/lib/translator.rb +27 -0
- data/lib/generators/i18n_translation/lib/yaml.rb +133 -0
- data/spec/spec_helper.rb +7 -36
- data/spec/yaml_spec.rb +101 -37
- metadata +38 -14
data/History.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,83 +1,54 @@
|
|
1
1
|
= I18n generators
|
2
2
|
|
3
|
-
This gem plugin generates a set of locale files for Rails
|
3
|
+
This gem plugin generates a set of locale files for Rails 3 i18n feature.
|
4
4
|
|
5
|
-
* http://github.com/amatsuda/i18n_generators
|
5
|
+
* http://github.com/amatsuda/i18n_generators
|
6
|
+
* http://rubygems.org/gems/i18n_generators
|
6
7
|
|
8
|
+
For Rails 2.3 and 2.2, use 0.8.x gem or rails2 branch.
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
This gem/plugin provides following four script/generate commands.
|
11
|
-
|
12
|
-
=== 1. Generate I18n Scaffold
|
13
|
-
|
14
|
-
% ./script/generate i18n_scaffold ja (de-AT, pt-BR, etc.)
|
15
|
-
|
16
|
-
Generates I18n aware scaffold.
|
10
|
+
* http://github.com/amatsuda/i18n_generators/tree/rails2
|
11
|
+
* http://rubygems.org/gems/i18n_generators/versions/0.8.1
|
17
12
|
|
18
|
-
|
13
|
+
== FEATURES
|
19
14
|
|
20
|
-
|
15
|
+
This gem/plugin provides following generate commands.
|
21
16
|
|
22
|
-
|
17
|
+
=== 1. Generate Locale Files for ActiveRecord/ActiveSupport/ActionPack
|
23
18
|
|
24
|
-
%
|
19
|
+
% rails g i18n_locale ja (de-AT, pt-BR, etc.)
|
25
20
|
|
26
|
-
|
21
|
+
Downloads the .yml file for the specified locale from the official rails-i18n repository:
|
22
|
+
http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale
|
27
23
|
|
28
|
-
Firstly, the generator checks here.
|
29
|
-
http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale
|
30
|
-
If the spacified .yml file exists in the repository, the generator downloads and puts the file into your config/locales directory.
|
31
24
|
Then the generater sets the application default locale to the specified locale.
|
32
25
|
|
33
26
|
This will generate following locale file.
|
34
27
|
|
35
28
|
config/locales/ja.yml
|
36
29
|
|
37
|
-
|
38
|
-
|
39
|
-
The generator copies the en.yml file (bundled inside Rails framework) into config/locales directory, and one-to-one localizes/translates each attribute value into the specified locale/language.
|
40
|
-
Then the generater sets the application default locale to the specified locale.
|
41
|
-
|
42
|
-
For example,
|
30
|
+
=== 2. Generate Translation YAML File For All Models/Attributes
|
43
31
|
|
44
|
-
%
|
45
|
-
|
46
|
-
will generate following locale files.
|
47
|
-
|
48
|
-
config/locales/active_support_zh.yml
|
49
|
-
config/locales/active_record_zh.yml
|
50
|
-
config/locales/action_view_zh.yml
|
51
|
-
|
52
|
-
=== 3. Generate Translation YAML File For All Models/Attributes and views/**/*.erb
|
53
|
-
|
54
|
-
% ./script/generate i18n_translation ja (de-AT, pt-BR, etc.)
|
55
|
-
|
56
|
-
or
|
57
|
-
|
58
|
-
% ./script/generate i18n --translation ja (de-AT, pt-BR, etc.)
|
32
|
+
% rails g i18n_translation ja (de-AT, pt-BR, etc.)
|
59
33
|
|
60
34
|
This will generate following YAML file.
|
61
35
|
|
62
36
|
config/locales/translation_ja.yml
|
63
37
|
|
64
38
|
The generator scans your app/models directory, and generates a YAML file with all the AR model names and attributes so that you don't have to write the YAML skeleton manually or by copy/paste.
|
65
|
-
In addition, the generator scans all the *.erb files in your app/views/** directory, and picks all the keys for I18n.translate, then adds them to the YAML file.
|
66
39
|
In addition, the generator tries to translate each of them into the specified language.
|
67
|
-
The generator doesn't overwrite the existing value so that you can rerun the generator again and again
|
40
|
+
The generator doesn't overwrite the existing value so that you can rerun the generator again and again.
|
68
41
|
|
69
|
-
===
|
42
|
+
=== 3. Generate All
|
70
43
|
|
71
|
-
%
|
44
|
+
% rails g i18n ja (de-AT, pt-BR, etc.)
|
72
45
|
|
73
|
-
Executes
|
46
|
+
Executes 1 and 2 at once.
|
74
47
|
|
75
48
|
|
76
49
|
== REQUIREMENTS:
|
77
50
|
|
78
|
-
* Ruby on Rails (>=
|
79
|
-
* Ruby-GetText-Package ( http://rubyforge.org/projects/gettext/ )
|
80
|
-
* high speed Internet connection
|
51
|
+
* Ruby on Rails (>= 3.0)
|
81
52
|
|
82
53
|
|
83
54
|
== INSTALL:
|
@@ -88,14 +59,7 @@ Executes 2 and 3 at once.
|
|
88
59
|
|
89
60
|
* As a Rails plugin
|
90
61
|
|
91
|
-
%
|
92
|
-
|
93
|
-
|
94
|
-
== CAUTION
|
95
|
-
|
96
|
-
Current version of this plugin is very very very roughly implemented just for experiment.
|
97
|
-
Every time you execute the generate command, the plugin connects to the Unicode CLDR website and scrapes the huge amount of its contents.
|
98
|
-
Please be careful not to harm your network environment and CLDR website by running this plugin too many times.
|
62
|
+
% rails plugin install git://github.com/amatsuda/i18n_generators.git
|
99
63
|
|
100
64
|
|
101
65
|
Copyright (c) 2008 Akira Matsuda, released under the MIT license
|
data/Rakefile
CHANGED
@@ -26,11 +26,12 @@ begin
|
|
26
26
|
require 'jeweler'
|
27
27
|
Jeweler::Tasks.new do |gemspec|
|
28
28
|
gemspec.name = 'i18n_generators'
|
29
|
-
gemspec.summary = 'Generates I18n locale files for Rails
|
30
|
-
gemspec.description = 'A Rails generator plugin & gem that generates Rails
|
29
|
+
gemspec.summary = 'Generates I18n locale files for Rails 3 and Rails 2'
|
30
|
+
gemspec.description = 'A Rails generator plugin & gem that generates Rails I18n locale files for almost every known locale.'
|
31
31
|
gemspec.email = 'ronnie@dio.jp'
|
32
32
|
gemspec.homepage = 'http://github.com/amatsuda/i18n_generators/'
|
33
33
|
gemspec.authors = ['Akira Matsuda']
|
34
|
+
gemspec.add_dependency 'yaml_waml'
|
34
35
|
end
|
35
36
|
Jeweler::GemcutterTasks.new
|
36
37
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0.pre1
|
data/generators/i18n/USAGE
CHANGED
@@ -82,4 +82,3 @@ end
|
|
82
82
|
require File.join(File.dirname(__FILE__), '../i18n_locale/i18n_locale_command')
|
83
83
|
require File.join(File.dirname(__FILE__), '../i18n_translation/i18n_translation_command')
|
84
84
|
Rails::Generator::Commands::Create.send :include, I18nGenerator::Generator::Commands::Create
|
85
|
-
|
@@ -1 +1 @@
|
|
1
|
-
<%= translations %>
|
1
|
+
<%= translations %>
|
@@ -44,7 +44,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
44
44
|
|
45
45
|
respond_to do |format|
|
46
46
|
if @<%= file_name %>.save
|
47
|
-
flash[:notice] = I18n.t(:created_success, :default => '{
|
47
|
+
flash[:notice] = I18n.t(:created_success, :default => '%{model} was successfully created.', :model => <%= class_name %>.human_name, :scope => [:railties, :scaffold])
|
48
48
|
format.html { redirect_to(@<%= file_name %>) }
|
49
49
|
format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
|
50
50
|
else
|
@@ -61,7 +61,7 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
61
61
|
|
62
62
|
respond_to do |format|
|
63
63
|
if @<%= file_name %>.update_attributes(params[:<%= file_name %>])
|
64
|
-
flash[:notice] = I18n.t(:updated_success, :default => '{
|
64
|
+
flash[:notice] = I18n.t(:updated_success, :default => '%{model} was successfully updated.', :model => <%= class_name %>.human_name, :scope => [:railties, :scaffold])
|
65
65
|
format.html { redirect_to(@<%= file_name %>) }
|
66
66
|
format.xml { head :ok }
|
67
67
|
else
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<h1><%% translate(:editing, :default => "Editing {
|
1
|
+
<h1><%% translate(:editing, :default => "Editing %{model}", :model => <%= class_name %>.human_name, :scope => [:railties, :scaffold]) %></h1>
|
2
2
|
|
3
3
|
<%% form_for(@<%= singular_name %>) do |f| %>
|
4
4
|
<%%= f.error_messages %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<h1><%%= translate(:listing, :default => "Listing {
|
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
2
|
|
3
3
|
<table>
|
4
4
|
<tr>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<h1><%%= translate(:new, :default => "New {
|
1
|
+
<h1><%%= translate(:new, :default => "New %{model}", :model => <%= class_name %>.human_name, :scope => [:railties, :scaffold]) %></h1>
|
2
2
|
|
3
3
|
<%% form_for(@<%= singular_name %>) do |f| %>
|
4
4
|
<%%= f.error_messages %>
|
data/i18n_generators.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{i18n_generators}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "1.0.0.pre1"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Akira Matsuda"]
|
12
|
-
s.date = %q{2010-10-
|
13
|
-
s.description = %q{A Rails generator plugin & gem that generates Rails
|
12
|
+
s.date = %q{2010-10-27}
|
13
|
+
s.description = %q{A Rails generator plugin & gem that generates Rails I18n locale files for almost every known locale.}
|
14
14
|
s.email = %q{ronnie@dio.jp}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.rdoc"
|
@@ -51,6 +51,14 @@ Gem::Specification.new do |s|
|
|
51
51
|
"generators/i18n_translation/lib/through_ryoku.rb",
|
52
52
|
"generators/i18n_translation/lib/translator.rb",
|
53
53
|
"i18n_generators.gemspec",
|
54
|
+
"lib/generators/i18n/USAGE",
|
55
|
+
"lib/generators/i18n/i18n_generator.rb",
|
56
|
+
"lib/generators/i18n_locale/USAGE",
|
57
|
+
"lib/generators/i18n_locale/i18n_locale_generator.rb",
|
58
|
+
"lib/generators/i18n_translation/USAGE",
|
59
|
+
"lib/generators/i18n_translation/i18n_translation_generator.rb",
|
60
|
+
"lib/generators/i18n_translation/lib/translator.rb",
|
61
|
+
"lib/generators/i18n_translation/lib/yaml.rb",
|
54
62
|
"spec/cldr_spec.rb",
|
55
63
|
"spec/data/cldr/ja.html",
|
56
64
|
"spec/data/yml/active_record/en-US.yml",
|
@@ -64,7 +72,7 @@ Gem::Specification.new do |s|
|
|
64
72
|
s.rdoc_options = ["--charset=UTF-8"]
|
65
73
|
s.require_paths = ["lib"]
|
66
74
|
s.rubygems_version = %q{1.3.7}
|
67
|
-
s.summary = %q{Generates I18n locale files for Rails
|
75
|
+
s.summary = %q{Generates I18n locale files for Rails 3 and Rails 2}
|
68
76
|
s.test_files = [
|
69
77
|
"spec/cldr_spec.rb",
|
70
78
|
"spec/i18n_locale_command_spec.rb",
|
@@ -79,9 +87,12 @@ Gem::Specification.new do |s|
|
|
79
87
|
s.specification_version = 3
|
80
88
|
|
81
89
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
90
|
+
s.add_runtime_dependency(%q<yaml_waml>, [">= 0"])
|
82
91
|
else
|
92
|
+
s.add_dependency(%q<yaml_waml>, [">= 0"])
|
83
93
|
end
|
84
94
|
else
|
95
|
+
s.add_dependency(%q<yaml_waml>, [">= 0"])
|
85
96
|
end
|
86
97
|
end
|
87
98
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Description:
|
2
|
+
Generates a config file and locale files and a model/attributes translation file for Rails i18n feature.
|
3
|
+
In other words, executes i18n_locale and i18n_translation at once.
|
4
|
+
|
5
|
+
Example:
|
6
|
+
% rails g i18n locale_name (ja, pt-BR, etc.)
|
7
|
+
|
8
|
+
This will create:
|
9
|
+
config/locales/ja.yml
|
10
|
+
config/locales/translation_ja.yml
|
11
|
+
And update:
|
12
|
+
config/application.rb
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../i18n_translation/i18n_translation_generator')
|
2
|
+
require File.join(File.dirname(__FILE__), '../i18n_locale/i18n_locale_generator')
|
3
|
+
|
4
|
+
class I18nGenerator < Rails::Generators::NamedBase
|
5
|
+
def initialize(args, *options)
|
6
|
+
super
|
7
|
+
@_args, @_options = args, options
|
8
|
+
end
|
9
|
+
|
10
|
+
def main
|
11
|
+
locale_gen = I18nLocaleGenerator.new(@_args, @_options)
|
12
|
+
locale_gen.main
|
13
|
+
|
14
|
+
translation_gen = I18nTranslationGenerator.new(@_args, @_options)
|
15
|
+
translation_gen.main
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class I18nLocaleGenerator < Rails::Generators::NamedBase
|
2
|
+
def main
|
3
|
+
unless file_name =~ /^[a-zA-Z]{2}([-_][a-zA-Z]+)?$/
|
4
|
+
log 'ERROR: Wrong locale format. Please input in ?? or ??-?? format.'
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
generate_configuration
|
8
|
+
fetch_from_rails_i18n_repository
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
def generate_configuration
|
13
|
+
return if I18n.default_locale.to_s == locale_name
|
14
|
+
log 'updating application.rb...'
|
15
|
+
# environment "config.i18n.default_locale = :#{locale_name}"
|
16
|
+
config = add_locale_config File.read(File.join(Rails.root, 'config/application.rb'))
|
17
|
+
create_file 'config/application.rb', config
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_locale_config(config_contents)
|
21
|
+
new_line = " config.i18n.default_locale = '#{locale_name}'"
|
22
|
+
if config_contents =~ /\n *config\.i18n\.default_locale *=/
|
23
|
+
config_contents.sub(/ *config\.i18n\.default_locale *=.*/, new_line)
|
24
|
+
elsif config_contents =~ /\n *#? *config\.i18n\.default_locale *=/
|
25
|
+
config_contents.sub(/ *#? *config\.i18n\.default_locale *=.*/, new_line)
|
26
|
+
elsif sentinel = config_contents.scan(/class [a-z_:]+ < Rails::Application/i).first
|
27
|
+
config_contents.sub sentinel, "#{sentinel}\n#{new_line}"
|
28
|
+
else
|
29
|
+
config_contents
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch_from_rails_i18n_repository
|
34
|
+
log "fetching #{locale_name}.yml from rails-i18n repository..."
|
35
|
+
begin
|
36
|
+
yml = OpenURI.open_uri("http://github.com/svenfuchs/rails-i18n/raw/master/rails/locale/#{locale_name}.yml").read
|
37
|
+
create_file "config/locales/#{locale_name}.yml", yml
|
38
|
+
rescue
|
39
|
+
log "could not find #{locale_name}.yml on rails-i18n repository"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def locale_name
|
44
|
+
@_locale_name ||= file_name.gsub('_', '-').split('-').each.with_index.map {|s, i| i == 0 ? s : s.upcase}.join('-')
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'lib/yaml')
|
2
|
+
require File.join(File.dirname(__FILE__), 'lib/translator')
|
3
|
+
|
4
|
+
class I18nTranslationGenerator < Rails::Generators::NamedBase
|
5
|
+
# option: include_timestamps
|
6
|
+
def main
|
7
|
+
unless file_name =~ /^[a-zA-Z]{2}([-_][a-zA-Z]+)?$/
|
8
|
+
log 'ERROR: Wrong locale format. Please input in ?? or ??-?? format.'
|
9
|
+
exit
|
10
|
+
end
|
11
|
+
log "translating models to #{locale_name}..."
|
12
|
+
I18n.locale = locale_name
|
13
|
+
|
14
|
+
keys = aggregate_keys
|
15
|
+
translations = translate_all(keys)
|
16
|
+
|
17
|
+
yaml = I27r::YamlDocument.load_yml_file "config/locales/translation_#{locale_name}.yml"
|
18
|
+
each_value [], translations do |parents, value|
|
19
|
+
if value.is_a? String
|
20
|
+
yaml[[locale_name.to_s] + parents] = value
|
21
|
+
else
|
22
|
+
value.each do |key, val|
|
23
|
+
yaml[[locale_name.to_s] + parents + [key]] = val
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
create_file "config/locales/translation_#{locale_name}.yml", yaml.to_s(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def aggregate_keys
|
33
|
+
models = model_filenames.map do |model_name|
|
34
|
+
model = begin
|
35
|
+
m = model_name.camelize.constantize rescue LoadError
|
36
|
+
next if m.nil? || !m.table_exists? || !m.respond_to?(:content_columns)
|
37
|
+
m.class_eval %Q[def self._english_name; "#{model_name}"; end]
|
38
|
+
m
|
39
|
+
rescue
|
40
|
+
next
|
41
|
+
end
|
42
|
+
end.compact
|
43
|
+
|
44
|
+
translation_keys = []
|
45
|
+
translation_keys += models.map {|m| "activerecord.models.#{m._english_name}"}
|
46
|
+
models.each do |model|
|
47
|
+
cols = model.content_columns + model.reflect_on_all_associations
|
48
|
+
cols.delete_if {|c| %w[created_at updated_at].include? c.name} unless include_timestamps?
|
49
|
+
translation_keys += cols.map {|c| "activerecord.attributes.#{model._english_name}.#{c.name}"}
|
50
|
+
end
|
51
|
+
translation_keys
|
52
|
+
end
|
53
|
+
|
54
|
+
# receives an array of keys and returns :key => :translation hash
|
55
|
+
def translate_all(keys)
|
56
|
+
translator = I27r::Translator.new locale_name.sub(/\-.*/, '')
|
57
|
+
|
58
|
+
ActiveSupport::OrderedHash.new.tap do |oh|
|
59
|
+
# fix the order first(for multi thread translating)
|
60
|
+
keys.each do |key|
|
61
|
+
if key.to_s.include? '.'
|
62
|
+
key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
|
63
|
+
key_prefix.inject(oh) {|h, k| h[k] ||= ActiveSupport::OrderedHash.new}[key_suffix] = nil
|
64
|
+
else
|
65
|
+
oh[key] = nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
threads = []
|
69
|
+
keys.each do |key|
|
70
|
+
threads << Thread.new do
|
71
|
+
Rails.logger.debug "translating #{key} ..."
|
72
|
+
Thread.pass
|
73
|
+
if key.to_s.include? '.'
|
74
|
+
key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
|
75
|
+
existing_translation = I18n.backend.send(:lookup, locale_name, key_suffix, key_prefix)
|
76
|
+
key_prefix.inject(oh) {|h, k| h[k]}[key_suffix] = existing_translation ? existing_translation : translator.translate(key_suffix)
|
77
|
+
else
|
78
|
+
existing_translation = I18n.backend.send(:lookup, locale_name, key)
|
79
|
+
oh[key] = existing_translation ? existing_translation : translator.translate(key)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
threads.each {|t| t.join}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def locale_name
|
88
|
+
@_locale_name ||= file_name.gsub('_', '-').split('-').each.with_index.map {|s, i| i == 0 ? s : s.upcase}.join('-')
|
89
|
+
end
|
90
|
+
|
91
|
+
def include_timestamps?
|
92
|
+
!!@include_timestamps
|
93
|
+
end
|
94
|
+
|
95
|
+
def model_filenames
|
96
|
+
Dir.chdir("#{Rails.root}/app/models/") do
|
97
|
+
Dir["**/*.rb"].map {|m| m.sub(/\.rb$/, '')}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# iterate through all values
|
102
|
+
def each_value(parents, src, &block)
|
103
|
+
src.each do |k, v|
|
104
|
+
if v.is_a?(ActiveSupport::OrderedHash)
|
105
|
+
each_value parents + [k], v, &block
|
106
|
+
else
|
107
|
+
yield parents + [k], v
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'json' if RUBY_VERSION >= '1.9'
|
3
|
+
|
4
|
+
module I27r
|
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
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'yaml_waml'
|
2
|
+
|
3
|
+
module I27r
|
4
|
+
class Line
|
5
|
+
attr_reader :text
|
6
|
+
delegate :scan, :to => :@text
|
7
|
+
|
8
|
+
def initialize(text, options = {})
|
9
|
+
@generated = !!options[:generated] || text.ends_with?(' #g')
|
10
|
+
@yaml = YAML.load text.to_s + ' '
|
11
|
+
@text = text
|
12
|
+
end
|
13
|
+
|
14
|
+
def key
|
15
|
+
yaml? ? @yaml.keys.first : nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def value
|
19
|
+
yaml? ? @yaml.values.first : nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def indent
|
23
|
+
yaml? ? @text.scan(/^ */).first : ''
|
24
|
+
end
|
25
|
+
|
26
|
+
def generated?
|
27
|
+
@generated
|
28
|
+
end
|
29
|
+
|
30
|
+
def yaml?
|
31
|
+
@yaml.is_a?(Hash) && @yaml.keys.first.is_a?(String)
|
32
|
+
end
|
33
|
+
|
34
|
+
def value=(val)
|
35
|
+
if @yaml[self.key] != val
|
36
|
+
@yaml[self.key] = val
|
37
|
+
generate_text self.indent
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
"#{@text}#{' #g' if generated? && yaml? && !value.nil? && !@text.ends_with?(' #g')}"
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def generate_text(indent)
|
47
|
+
@text = indent + @yaml.to_yaml.sub("--- \n", '').chomp.rstrip
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class YamlDocument
|
52
|
+
attr_accessor :root
|
53
|
+
|
54
|
+
def initialize(yaml = '')
|
55
|
+
@lines = yaml.split("\n").map {|s| Line.new s}
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.load_yml_file(yml_path)
|
59
|
+
if File.exists? yml_path
|
60
|
+
self.new File.read(yml_path)
|
61
|
+
else
|
62
|
+
self.new
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def [](*path)
|
67
|
+
find_line_by_path(path.flatten).try :value
|
68
|
+
end
|
69
|
+
|
70
|
+
def find_line_by_path(path, line_num = -1, add_new = false)
|
71
|
+
key = path.shift
|
72
|
+
indent = line_num == -1 ? '' : @lines[line_num].scan(/^ */).first + ' '
|
73
|
+
@lines[(line_num + 1)..-1].each do |line|
|
74
|
+
line_num += 1
|
75
|
+
next unless line.yaml?
|
76
|
+
|
77
|
+
if (line.indent == indent) && (line.key == key)
|
78
|
+
if path.empty?
|
79
|
+
return line
|
80
|
+
else
|
81
|
+
return find_line_by_path path, line_num, add_new
|
82
|
+
end
|
83
|
+
elsif line.indent < indent
|
84
|
+
if add_new
|
85
|
+
new_line = Line.new("#{indent}#{key}:", :generated => true)
|
86
|
+
if @lines[line_num - 1].try(:text) == ''
|
87
|
+
@lines.insert line_num - 1, new_line
|
88
|
+
else
|
89
|
+
@lines.insert line_num, new_line
|
90
|
+
end
|
91
|
+
return new_line if path.empty?
|
92
|
+
return find_line_by_path path, line_num, add_new
|
93
|
+
else
|
94
|
+
return
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
if add_new
|
99
|
+
new_line = Line.new("#{indent}#{key}:", :generated => true)
|
100
|
+
@lines.insert @lines.count, new_line
|
101
|
+
return new_line if path.empty?
|
102
|
+
return find_line_by_path path, @lines.count - 1, add_new
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def []=(*args)
|
107
|
+
value = args.pop
|
108
|
+
path = args.flatten
|
109
|
+
# return if value && (value == self[path])
|
110
|
+
|
111
|
+
line = find_line_by_path path.dup
|
112
|
+
if line
|
113
|
+
if line.generated?
|
114
|
+
line.value = value
|
115
|
+
end
|
116
|
+
else
|
117
|
+
line = find_line_by_path path, -1, true
|
118
|
+
line.value = value
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_s(add_blank_line = false)
|
123
|
+
previous_indent = ''
|
124
|
+
''.tap do |ret|
|
125
|
+
@lines.each do |line|
|
126
|
+
ret << "\n" if add_blank_line && (line.indent < previous_indent) && !line.to_s.blank? && !ret.ends_with?("\n\n")
|
127
|
+
previous_indent = line.indent
|
128
|
+
ret << line.to_s << "\n"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,39 +1,10 @@
|
|
1
|
-
|
2
|
-
# from the project root directory.
|
3
|
-
require 'rubygems'
|
4
|
-
require 'spec'
|
5
|
-
require 'activesupport'
|
1
|
+
require 'active_support/all'
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# fixtures :table_a, :table_b
|
13
|
-
#
|
14
|
-
# Alternatively, if you prefer to declare them only once, you can
|
15
|
-
# do so right here. Just uncomment the next line and replace the fixture
|
16
|
-
# names with your fixtures.
|
17
|
-
#
|
18
|
-
# config.global_fixtures = :table_a, :table_b
|
19
|
-
#
|
20
|
-
# If you declare global fixtures, be aware that they will be declared
|
21
|
-
# for all of your examples, even those that don't use them.
|
22
|
-
#
|
23
|
-
# You can also declare which fixtures to use (for example fixtures for test/fixtures):
|
24
|
-
#
|
25
|
-
# config.fixture_path = RAILS_ROOT + '/spec/fixtures/'
|
26
|
-
#
|
27
|
-
# == Mock Framework
|
28
|
-
#
|
29
|
-
# RSpec uses it's own mocking framework by default. If you prefer to
|
30
|
-
# use mocha, flexmock or RR, uncomment the appropriate line:
|
31
|
-
#
|
32
|
-
# config.mock_with :mocha
|
33
|
-
# config.mock_with :flexmock
|
3
|
+
# Requires supporting files with custom matchers and macros, etc,
|
4
|
+
# in ./support/ and its subdirectories.
|
5
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
34
8
|
# config.mock_with :rr
|
35
|
-
|
36
|
-
# == Notes
|
37
|
-
#
|
38
|
-
# For more information take a look at Spec::Example::Configuration and Spec::Runner
|
9
|
+
config.mock_with :rspec
|
39
10
|
end
|
data/spec/yaml_spec.rb
CHANGED
@@ -1,59 +1,123 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
require File.join(File.dirname(__FILE__), '
|
2
|
+
require File.join(File.dirname(__FILE__), '../lib/generators/i18n_translation/lib/yaml')
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
describe I27r::YamlDocument do
|
5
|
+
context 'when loading an existing file' do
|
6
|
+
before do
|
7
|
+
@yaml_string = <<YAML
|
8
|
+
ja:
|
9
|
+
hoge:
|
10
|
+
fuga: piyo #g
|
11
|
+
numbers:
|
12
|
+
one: "いち" #g
|
13
|
+
two: "に"
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
aaa:
|
16
|
+
foo: "ふー"
|
17
|
+
bar: "ばー"
|
18
|
+
YAML
|
19
|
+
@yaml = I27r::YamlDocument.new @yaml_string
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
22
|
+
subject { @yaml }
|
23
|
+
it { should be }
|
22
24
|
|
23
|
-
|
24
|
-
before do
|
25
|
-
@node = Node.new @yaml, 100, 'foo: bar'
|
26
|
-
end
|
25
|
+
its(:to_s) { should == @yaml_string }
|
27
26
|
|
28
|
-
|
29
|
-
|
27
|
+
describe '[]' do
|
28
|
+
specify '[]' do
|
29
|
+
@yaml['ja', 'hoge', 'fuga'].should == 'piyo'
|
30
|
+
@yaml[['ja', 'hoge', 'fuga']].should == 'piyo'
|
31
|
+
end
|
30
32
|
end
|
31
33
|
|
32
|
-
|
33
|
-
@
|
34
|
+
describe 'find_line_by_path' do
|
35
|
+
subject { @yaml.find_line_by_path(['ja', 'hoge', 'fuga']) }
|
36
|
+
its(:value) { should == 'piyo' }
|
34
37
|
end
|
35
38
|
|
36
|
-
|
37
|
-
@yaml['ja'
|
39
|
+
describe 'find_line_by_path' do
|
40
|
+
subject { @yaml.find_line_by_path(['ja', 'aho', 'hage'], -1, true) }
|
41
|
+
it { should be }
|
42
|
+
its(:key) { should == 'hage' }
|
43
|
+
its(:value) { should_not be }
|
38
44
|
end
|
39
45
|
|
40
|
-
describe '[]
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
it
|
46
|
+
describe '[]=' do
|
47
|
+
context 'rewriting an existing value' do
|
48
|
+
before { @yaml['ja', 'hoge', 'fuga'] = 'puyo' }
|
49
|
+
subject { @yaml['ja', 'hoge', 'fuga'] }
|
50
|
+
it { should == 'puyo' }
|
45
51
|
end
|
46
52
|
|
47
|
-
|
48
|
-
|
53
|
+
context 'an existing value without #g mark' do
|
54
|
+
before { @yaml['ja', 'hoge', 'numbers', 'two'] = 'ツー' }
|
55
|
+
subject { @yaml['ja', 'hoge', 'numbers', 'two'] }
|
56
|
+
it { should == 'に' }
|
57
|
+
end
|
49
58
|
|
50
|
-
|
59
|
+
context 'creating a new node in the middle' do
|
60
|
+
before { @yaml['ja', 'hoge', 'numbers', 'three'] = 'さん' }
|
61
|
+
subject { @yaml['ja', 'hoge', 'numbers', 'three'] }
|
62
|
+
it { should == 'さん' }
|
63
|
+
specify do
|
64
|
+
@yaml.to_s.should == <<YAML
|
65
|
+
ja:
|
66
|
+
hoge:
|
67
|
+
fuga: piyo #g
|
68
|
+
numbers:
|
69
|
+
one: "いち" #g
|
70
|
+
two: "に"
|
71
|
+
three: "さん" #g
|
51
72
|
|
52
|
-
|
73
|
+
aaa:
|
74
|
+
foo: "ふー"
|
75
|
+
bar: "ばー"
|
76
|
+
YAML
|
77
|
+
end
|
78
|
+
end
|
53
79
|
|
54
|
-
|
80
|
+
context 'creating a new node at the bottom' do
|
81
|
+
before { @yaml['ja', 'aho', 'hage'] = 'hige' }
|
82
|
+
subject { @yaml['ja', 'aho', 'hage'] }
|
83
|
+
it { should == 'hige' }
|
55
84
|
end
|
85
|
+
|
56
86
|
end
|
57
87
|
end
|
58
|
-
end
|
59
88
|
|
89
|
+
context 'when loading an existing file with alias' do
|
90
|
+
before do
|
91
|
+
@yaml_string = <<YAML
|
92
|
+
ja:
|
93
|
+
activerecord:
|
94
|
+
attributes:
|
95
|
+
hoge: &hoge
|
96
|
+
foo: FOO
|
97
|
+
bar: BAR
|
98
|
+
hoge2: &hoge2
|
99
|
+
hoge:
|
100
|
+
<<: *hogege
|
101
|
+
YAML
|
102
|
+
@yaml = I27r::YamlDocument.new @yaml_string
|
103
|
+
@yaml['ja', 'activerecord', 'hoge2', 'hoge'] = 'foo'
|
104
|
+
end
|
105
|
+
|
106
|
+
specify '' do
|
107
|
+
puts @yaml.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'creating a new file' do
|
112
|
+
before do
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
specify 'that' do
|
117
|
+
yaml = I27r::YamlDocument.new
|
118
|
+
yaml['ja', 'hoge', 'fuga'] = 'piyo'
|
119
|
+
yaml['ja', 'hoge', 'foo'] = 'bar'
|
120
|
+
puts yaml
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n_generators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: -1876988176
|
5
|
+
prerelease: true
|
6
6
|
segments:
|
7
|
-
- 0
|
8
|
-
- 8
|
9
7
|
- 1
|
10
|
-
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
- pre1
|
11
|
+
version: 1.0.0.pre1
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- Akira Matsuda
|
@@ -15,11 +16,24 @@ autorequire:
|
|
15
16
|
bindir: bin
|
16
17
|
cert_chain: []
|
17
18
|
|
18
|
-
date: 2010-10-
|
19
|
+
date: 2010-10-27 00:00:00 +09:00
|
19
20
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
22
|
-
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: yaml_waml
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: A Rails generator plugin & gem that generates Rails I18n locale files for almost every known locale.
|
23
37
|
email: ronnie@dio.jp
|
24
38
|
executables: []
|
25
39
|
|
@@ -63,6 +77,14 @@ files:
|
|
63
77
|
- generators/i18n_translation/lib/through_ryoku.rb
|
64
78
|
- generators/i18n_translation/lib/translator.rb
|
65
79
|
- i18n_generators.gemspec
|
80
|
+
- lib/generators/i18n/USAGE
|
81
|
+
- lib/generators/i18n/i18n_generator.rb
|
82
|
+
- lib/generators/i18n_locale/USAGE
|
83
|
+
- lib/generators/i18n_locale/i18n_locale_generator.rb
|
84
|
+
- lib/generators/i18n_translation/USAGE
|
85
|
+
- lib/generators/i18n_translation/i18n_translation_generator.rb
|
86
|
+
- lib/generators/i18n_translation/lib/translator.rb
|
87
|
+
- lib/generators/i18n_translation/lib/yaml.rb
|
66
88
|
- spec/cldr_spec.rb
|
67
89
|
- spec/data/cldr/ja.html
|
68
90
|
- spec/data/yml/active_record/en-US.yml
|
@@ -92,19 +114,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
115
|
none: false
|
94
116
|
requirements:
|
95
|
-
- - "
|
117
|
+
- - ">"
|
96
118
|
- !ruby/object:Gem::Version
|
97
|
-
hash:
|
119
|
+
hash: 25
|
98
120
|
segments:
|
99
|
-
-
|
100
|
-
|
121
|
+
- 1
|
122
|
+
- 3
|
123
|
+
- 1
|
124
|
+
version: 1.3.1
|
101
125
|
requirements: []
|
102
126
|
|
103
127
|
rubyforge_project:
|
104
128
|
rubygems_version: 1.3.7
|
105
129
|
signing_key:
|
106
130
|
specification_version: 3
|
107
|
-
summary: Generates I18n locale files for Rails
|
131
|
+
summary: Generates I18n locale files for Rails 3 and Rails 2
|
108
132
|
test_files:
|
109
133
|
- spec/cldr_spec.rb
|
110
134
|
- spec/i18n_locale_command_spec.rb
|