i18n_generators 0.8.1 → 1.0.0.pre1
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/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
|