ready_for_i18n 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 zigzag
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.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = ready_for_i18n
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2009 zigzag. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "ready_for_i18n"
8
+ gem.summary = "ready_for_i18n is a tool helping for the very first step of transfering your local Rails project to an i18n one."
9
+ gem.description = <<END_OF_DESC
10
+ ready_for_i18n will help you extract visible hard-coded text from your ERB view files,
11
+ then choose a proper key and replace them with the I18n.translate method like t(:login)
12
+ END_OF_DESC
13
+
14
+ gem.email = "zigzag.chen@gmail.com"
15
+ gem.homepage = "http://github.com/zigzag/ready_for_i18n"
16
+ gem.authors = ["zigzag"]
17
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ Jeweler::GemcutterTasks.new
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
+ end
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/test_*.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ begin
33
+ require 'rcov/rcovtask'
34
+ Rcov::RcovTask.new do |test|
35
+ test.libs << 'test'
36
+ test.pattern = 'test/**/test_*.rb'
37
+ test.verbose = true
38
+ end
39
+ rescue LoadError
40
+ task :rcov do
41
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
42
+ end
43
+ end
44
+
45
+ task :test => :check_dependencies
46
+
47
+ task :default => :test
48
+
49
+ require 'rake/rdoctask'
50
+ Rake::RDocTask.new do |rdoc|
51
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
52
+
53
+ rdoc.rdoc_dir = 'rdoc'
54
+ rdoc.title = "ready_for_i18n #{version}"
55
+ rdoc.rdoc_files.include('README*')
56
+ rdoc.rdoc_files.include('lib/**/*.rb')
57
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.2
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ help = <<HELP
6
+ ******************************************************************************
7
+ ready_for_i18n is a handy tool in the first step of transfering your local
8
+ Rails project to an i18n one.
9
+
10
+ It will automatically extract hard-coded text from your ERB view file,
11
+ then choose a proper key and replace them with the I18n.translate method.
12
+
13
+ Basic Command Line Usage:
14
+ ready_for_i18n <path to ERB source files> <target path>
15
+
16
+ # Your erb files in source path will be transformed(i18n_ready)
17
+ # and copy to target file path,together with a locale file 'en.yml'.
18
+
19
+ # using the following options:
20
+
21
+ HELP
22
+
23
+ require 'optparse'
24
+ require 'fileutils'
25
+ require 'ready_for_i18n'
26
+
27
+ options = {}
28
+ opts = OptionParser.new do |opts|
29
+ opts.banner = help
30
+ opts.on("--locale [LOCALE]", "Generating for the specified locale (default locale 'en')") do |locale|
31
+ options['locale'] = locale unless locale.nil?
32
+ end
33
+
34
+ opts.on("--ext [EXTENSION]", "The file extension name of your views(default '.html.erb')") do |extension|
35
+ options['extension'] = extension unless extension.nil?
36
+ end
37
+
38
+ end
39
+
40
+ # Read command line options into `options` hash
41
+ opts.parse!
42
+
43
+ # Get source and destintation from command line
44
+ case ARGV.size
45
+ when 2
46
+ options['source'] = ARGV[0]
47
+ options['destination'] = ARGV[1]
48
+ else
49
+ puts "Invalid options. Run `ready_for_i18n --help` for assistance."
50
+ exit(1)
51
+ end
52
+
53
+ def excute(src_path,target_path,locale,extension)
54
+ ext = extension || '.html.erb'
55
+ dict = ReadyForI18N::LocaleDictionary.new(locale)
56
+ Dir.glob(File.join(src_path,"**/*#{ext}")).each do |f|
57
+ full_target_path = File.dirname(f).gsub(src_path,target_path)
58
+ FileUtils.makedirs full_target_path
59
+ target_file = File.join(full_target_path,File.basename(f))
60
+ ReadyForI18N::LabelExtractor.new(f,target_file).extract{|k,v| dict[k] = v}
61
+ ReadyForI18N::TextExtractor.new(target_file,target_file).extract{|k,v| dict[k] = v}
62
+ puts "i18n ready: #{target_file}"
63
+ end
64
+ locale_file = dict.write_to target_path
65
+ puts "------------------------------------------------------------------------------"
66
+ puts "Locale file: #{locale_file}"
67
+ end
68
+
69
+ # Run the i18n generating
70
+ excute(options['source'],options['destination'],options['locale'],options['extension'])
@@ -0,0 +1,28 @@
1
+ module ReadyForI18N
2
+ module BaseExtractor
3
+ def initialize(erb_source, erb_target = nil)
4
+ @erb_source = erb_source
5
+ @erb_target = erb_target
6
+ end
7
+
8
+ def extract
9
+ buffer = ''
10
+ File.open(@erb_source).each do |line|
11
+ unless skip_line?(line)
12
+ values_in_line(line).each do |e|
13
+ if to_value(e).size > 1
14
+ yield(to_key(e),to_value(e)) if block_given?
15
+ replace_line(line,e)
16
+ end
17
+ end
18
+ end
19
+ buffer << line
20
+ end
21
+ File.open(@erb_target,'w+') {|f| f << buffer} if @erb_target
22
+ end
23
+ def to_key(s)
24
+ result = to_value(s).scan(/\w+/).join('_').downcase
25
+ key_prefix ? "#{key_prefix}_#{result}" : result
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ require 'ready_for_i18n'
2
+ require 'fileutils'
3
+
4
+ module ReadyForI18N
5
+ class I18nAutomator
6
+ def self.run(src_erb_path,target_erb_path,locale_path,locale)
7
+ dict = ReadyForI18N::LocaleDictionary.new(locale)
8
+ Dir.glob(File.join(src_erb_path,'**/*.html.erb')).each do |f|
9
+ target_path = File.dirname(f).gsub(src_erb_path,target_erb_path)
10
+ FileUtils.makedirs target_path
11
+ target_file = File.join(target_path,File.basename(f))
12
+ ReadyForI18N::LabelExtractor.new(f,target_file).extract{|k,v| dict[k] = v}
13
+ ReadyForI18N::TextExtractor.new(target_file,target_file).extract{|k,v| dict[k] = v}
14
+ end
15
+ dict.write_to locale_path
16
+ end
17
+ end
18
+ end
19
+
20
+
21
+ srcpath = "/Users/zig/workspace/sonar/tags/1.12/sonar-web/src/main/webapp/WEB-INF/app/views"
22
+ ReadyForI18N::I18nAutomator.run(srcpath,'/tmp','/tmp','en')
@@ -0,0 +1,24 @@
1
+ module ReadyForI18N
2
+ class LabelExtractor
3
+ LABEL_IN_HELPER_PATTERN = %w{label_tag link_to field_set_tag}.map{|h| /#{h}[\s\w_]*('|")([\w ]*)(\1)/ }
4
+
5
+ include ReadyForI18N::BaseExtractor
6
+
7
+ protected
8
+ def values_in_line(line)
9
+ LABEL_IN_HELPER_PATTERN.map{|h| line.match(h).captures.join if line =~ h}.compact
10
+ end
11
+ def skip_line?(s)
12
+ false
13
+ end
14
+ def to_value(s)
15
+ s.strip[1..-2]
16
+ end
17
+ def replace_line(line,e)
18
+ line.gsub!(e,"t(:#{to_key(e)})")
19
+ end
20
+ def key_prefix
21
+ 'label'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ module ReadyForI18N
2
+ class LocaleDictionary
3
+ def initialize(locale = nil)
4
+ @locale = locale || 'en'
5
+ @hash = {}
6
+ end
7
+ def []=(key,value)
8
+ @hash[key] = value
9
+ end
10
+
11
+ def write_to(path)
12
+ file = File.join(path,"#{@locale}.yml")
13
+ File.open(file,'w+') do |f|
14
+ f.puts "#{@locale}:"
15
+ @hash.keys.sort{|a,b|a.to_s<=>b.to_s}.each { |k| f.puts " #{k}: \"#{@hash[k]}\"" }
16
+ end
17
+ file
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ require 'base_extractor'
2
+ require 'text_extractor'
3
+ require 'label_extractor'
4
+ require 'locale_dictionary'
@@ -0,0 +1,37 @@
1
+ module ReadyForI18N
2
+ class TextExtractor
3
+ SKIP_TAGS = [[/<script/i,/<\/script>/i],[/<%/,/%>/],[/<style/i,/\/style>/i]]
4
+ SKIP_INLINE_TAG = [/<%(.*?)%>/,/<(.*?)>/,/<%(.*)$/,/^(.*)%>/,/&nbsp;/,/&raquo;/]
5
+ SEPERATOR = '_@@@_'
6
+
7
+ include ReadyForI18N::BaseExtractor
8
+
9
+ protected
10
+ def values_in_line(line)
11
+ SKIP_INLINE_TAG.inject(line.clone){|memo,tag| memo.gsub(tag,SEPERATOR)}.strip.split SEPERATOR
12
+ end
13
+ def skip_line?(s)
14
+ @stack ||= []
15
+ return true if s.nil? || s.strip.size == 0
16
+ jump_in_tag = SKIP_TAGS.find{ |start_tag,end_tag| s =~ start_tag}
17
+ @stack.push jump_in_tag[1] if jump_in_tag
18
+ if @stack.last
19
+ end_tag_match = s.match(@stack.last)
20
+ if end_tag_match
21
+ @stack.pop
22
+ return skip_line?(end_tag_match.post_match)
23
+ end
24
+ end
25
+ return !@stack.empty?
26
+ end
27
+ def to_value(s)
28
+ s.strip
29
+ end
30
+ def replace_line(line,e)
31
+ line.gsub!(e,"<%=t(:#{to_key(e)})%>")
32
+ end
33
+ def key_prefix
34
+ 'text'
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ready_for_i18n}
8
+ s.version = "0.2.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["zigzag"]
12
+ s.date = %q{2009-12-15}
13
+ s.default_executable = %q{ready_for_i18n}
14
+ s.description = %q{ ready_for_i18n will help you extract visible hard-coded text from your ERB view files,
15
+ then choose a proper key and replace them with the I18n.translate method like t(:login)
16
+ }
17
+ s.email = %q{zigzag.chen@gmail.com}
18
+ s.executables = ["ready_for_i18n"]
19
+ s.extra_rdoc_files = [
20
+ "LICENSE",
21
+ "README.rdoc"
22
+ ]
23
+ s.files = [
24
+ ".document",
25
+ ".gitignore",
26
+ "LICENSE",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "bin/ready_for_i18n",
31
+ "lib/base_extractor.rb",
32
+ "lib/i18n_automator.rb",
33
+ "lib/label_extractor.rb",
34
+ "lib/locale_dictionary.rb",
35
+ "lib/ready_for_i18n.rb",
36
+ "lib/text_extractor.rb",
37
+ "ready_for_i18n.gemspec",
38
+ "test/fixtures/index.html.erb",
39
+ "test/helper.rb",
40
+ "test/output/en.yml",
41
+ "test/output/label.html.erb",
42
+ "test/output/text.html.erb",
43
+ "test/test_base_extractor.rb",
44
+ "test/test_label_extractor.rb",
45
+ "test/test_locale_dictionary.rb",
46
+ "test/test_text_extrator.rb"
47
+ ]
48
+ s.homepage = %q{http://github.com/zigzag/ready_for_i18n}
49
+ s.rdoc_options = ["--charset=UTF-8"]
50
+ s.require_paths = ["lib"]
51
+ s.rubygems_version = %q{1.3.5}
52
+ s.summary = %q{ready_for_i18n is a tool helping for the very first step of transfering your local Rails project to an i18n one.}
53
+ s.test_files = [
54
+ "test/helper.rb",
55
+ "test/test_base_extractor.rb",
56
+ "test/test_label_extractor.rb",
57
+ "test/test_locale_dictionary.rb",
58
+ "test/test_text_extrator.rb"
59
+ ]
60
+
61
+ if s.respond_to? :specification_version then
62
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
63
+ s.specification_version = 3
64
+
65
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
66
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
67
+ else
68
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
69
+ end
70
+ else
71
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
72
+ end
73
+ end
74
+
@@ -0,0 +1,89 @@
1
+ <table width="100%">
2
+ <tr>
3
+ <td valign="top">
4
+ <h1>Users</h1>
5
+ <br/>
6
+ <table class="data sortable" id="users">
7
+ <thead>
8
+ <tr>
9
+ <th class="left">Login</th>
10
+ <th class="left">Name</th>
11
+ <th class="left nosort">Groups</th>
12
+ <th class="left nosort" nowrap>Operations</th>
13
+ </tr>
14
+ </thead>
15
+ <tbody >
16
+ <% @users.each do |user|%>
17
+ <% clazz = cycle("even", "odd", :name => 'index_user') %>
18
+ <tr id="user-<%= u user.login -%>">
19
+ <td class="left" valign="top"><%=user.login %></td>
20
+ <td class="left" valign="top"><%=user.name %></td>
21
+ <td class="left" valign="top">
22
+ <%= user.groups.sort.map(&:name).join(', ') %> (<%= link_to "select", {:action => 'select_group', :id => user.id}, :id => "select-#{u user.login}" %>)
23
+ </td>
24
+ <td class="left" valign="top">
25
+ <%= link_to "edit", { :id => user.id, :action => 'edit'}, :id => "edit-#{u user.login}" %> |
26
+ <%= link_to "delete", {:action => 'destroy', :id => user.id}, {:confirm => "Warning : are you sure to delete this user ?", :method => 'delete', :id => "delete-#{u user.login}"} %>
27
+ </td>
28
+ </tr>
29
+ <% end %>
30
+ </tbody>
31
+ </table>
32
+ </td>
33
+ <td class="sep"> </td>
34
+ <td valign="top" align="right" width="210">
35
+ <%
36
+ action_name = 'create'
37
+ title='Add new user'
38
+ if @user.id
39
+ action_name = 'update'
40
+ title='Edit user'
41
+ end
42
+ %>
43
+ <% form_for :user, @user, :url => { :id => @user.id, :action => action_name}, :html => { :method => @user.id.nil?? :post : :put } do |f| %>
44
+ <table class="admintable" width="100%">
45
+ <tr>
46
+ <td class="left" valign="top"><h1><%= title %></h1></td>
47
+ </tr>
48
+ <tr>
49
+ <td class="left" valign="top">Login:
50
+ <% if @user.id %>
51
+ <%= @user.login %>
52
+ <%= f.hidden_field :login %>
53
+
54
+ <% else %>
55
+ <br/><%= f.text_field :login, :size => 30, :maxLength => 40 %>
56
+ <% end %>
57
+ </td>
58
+ </tr>
59
+ <tr>
60
+ <td class="left" valign="top">Name:<br/><%= f.text_field :name, :size => 30, :maxLength => 200 %></td>
61
+ </tr>
62
+ <tr>
63
+ <td class="left" valign="top">Password:<br/><%= f.password_field :password, :size => 30, :maxLength => 50 %></td>
64
+ </tr>
65
+ <tr>
66
+ <td class="left" valign="top">Confirm password:<br/><%= f.password_field :password_confirmation, :size => 30, :maxLength => 50 %></td>
67
+ </tr>
68
+ <tr>
69
+ <td class="left" nowrap="nowrap" valign="top" colspan="2">
70
+ <%= submit_tag @user.id.nil?? 'Create':'Update' %>
71
+ <%= link_to 'cancel', { :controller => 'users', :action => 'index'}, { :class => 'action' } %><br/>
72
+ </td>
73
+ </tr>
74
+
75
+ </table>
76
+ <% end %>
77
+ </td>
78
+ </tr>
79
+ </table>
80
+
81
+ <%= link_to "export",
82
+ url_for(:controller => 'api/rules', :action => 'index', :language => @profile.language, :profile => @profile.name,
83
+ :plugins => @plugins.join(','),
84
+ :status => @status, :searchtext => @searchtext, :priorities => @priorities.join(','), :categories => @categories.join(','),
85
+ :format => 'csv'),
86
+ :class => 'action' %>&nbsp;&nbsp;Export
87
+
88
+ <%= link_to_remote 'Add Event', {:url => { :controller => 'events', :action => "new", :rid => params['rid'] },
89
+ :update => "event_form"}, {:class => 'action'} %>
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'ready_for_i18n'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,4 @@
1
+ en:
2
+ label: "OK"
3
+ login_key: "Login:"
4
+ text: "Please Confirm:"
@@ -0,0 +1,89 @@
1
+ <table width="100%">
2
+ <tr>
3
+ <td valign="top">
4
+ <h1>Users</h1>
5
+ <br/>
6
+ <table class="data sortable" id="users">
7
+ <thead>
8
+ <tr>
9
+ <th class="left">Login</th>
10
+ <th class="left">Name</th>
11
+ <th class="left nosort">Groups</th>
12
+ <th class="left nosort" nowrap>Operations</th>
13
+ </tr>
14
+ </thead>
15
+ <tbody >
16
+ <% @users.each do |user|%>
17
+ <% clazz = cycle("even", "odd", :name => 'index_user') %>
18
+ <tr id="user-<%= u user.login -%>">
19
+ <td class="left" valign="top"><%=user.login %></td>
20
+ <td class="left" valign="top"><%=user.name %></td>
21
+ <td class="left" valign="top">
22
+ <%= user.groups.sort.map(&:name).join(', ') %> (<%= link_to t(:label_select), {:action => 'select_group', :id => user.id}, :id => "select-#{u user.login}" %>)
23
+ </td>
24
+ <td class="left" valign="top">
25
+ <%= link_to t(:label_edit), { :id => user.id, :action => 'edit'}, :id => "edit-#{u user.login}" %> |
26
+ <%= link_to t(:label_delete), {:action => 'destroy', :id => user.id}, {:confirm => "Warning : are you sure to delete this user ?", :method => 'delete', :id => "delete-#{u user.login}"} %>
27
+ </td>
28
+ </tr>
29
+ <% end %>
30
+ </tbody>
31
+ </table>
32
+ </td>
33
+ <td class="sep"> </td>
34
+ <td valign="top" align="right" width="210">
35
+ <%
36
+ action_name = 'create'
37
+ title='Add new user'
38
+ if @user.id
39
+ action_name = 'update'
40
+ title='Edit user'
41
+ end
42
+ %>
43
+ <% form_for :user, @user, :url => { :id => @user.id, :action => action_name}, :html => { :method => @user.id.nil?? :post : :put } do |f| %>
44
+ <table class="admintable" width="100%">
45
+ <tr>
46
+ <td class="left" valign="top"><h1><%= title %></h1></td>
47
+ </tr>
48
+ <tr>
49
+ <td class="left" valign="top">Login:
50
+ <% if @user.id %>
51
+ <%= @user.login %>
52
+ <%= f.hidden_field :login %>
53
+
54
+ <% else %>
55
+ <br/><%= f.text_field :login, :size => 30, :maxLength => 40 %>
56
+ <% end %>
57
+ </td>
58
+ </tr>
59
+ <tr>
60
+ <td class="left" valign="top">Name:<br/><%= f.text_field :name, :size => 30, :maxLength => 200 %></td>
61
+ </tr>
62
+ <tr>
63
+ <td class="left" valign="top">Password:<br/><%= f.password_field :password, :size => 30, :maxLength => 50 %></td>
64
+ </tr>
65
+ <tr>
66
+ <td class="left" valign="top">Confirm password:<br/><%= f.password_field :password_confirmation, :size => 30, :maxLength => 50 %></td>
67
+ </tr>
68
+ <tr>
69
+ <td class="left" nowrap="nowrap" valign="top" colspan="2">
70
+ <%= submit_tag @user.id.nil?? 'Create':'Update' %>
71
+ <%= link_to t(:label_cancel), { :controller => 'users', :action => 'index'}, { :class => 'action' } %><br/>
72
+ </td>
73
+ </tr>
74
+
75
+ </table>
76
+ <% end %>
77
+ </td>
78
+ </tr>
79
+ </table>
80
+
81
+ <%= link_to t(:label_export),
82
+ url_for(:controller => 'api/rules', :action => 'index', :language => @profile.language, :profile => @profile.name,
83
+ :plugins => @plugins.join(','),
84
+ :status => @status, :searchtext => @searchtext, :priorities => @priorities.join(','), :categories => @categories.join(','),
85
+ :format => 'csv'),
86
+ :class => 'action' %>&nbsp;&nbsp;Export
87
+
88
+ <%= link_to_remote t(:label_add_event), {:url => { :controller => 'events', :action => "new", :rid => params['rid'] },
89
+ :update => "event_form"}, {:class => 'action'} %>
@@ -0,0 +1,89 @@
1
+ <table width="100%">
2
+ <tr>
3
+ <td valign="top">
4
+ <h1><%=t(:text_users)%></h1>
5
+ <br/>
6
+ <table class="data sortable" id="users">
7
+ <thead>
8
+ <tr>
9
+ <th class="left"><%=t(:text_login)%></th>
10
+ <th class="left"><%=t(:text_name)%></th>
11
+ <th class="left nosort"><%=t(:text_groups)%></th>
12
+ <th class="left nosort" nowrap><%=t(:text_operations)%></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody >
16
+ <% @users.each do |user|%>
17
+ <% clazz = cycle("even", "odd", :name => 'index_user') %>
18
+ <tr id="user-<%= u user.login -%>">
19
+ <td class="left" valign="top"><%=user.login %></td>
20
+ <td class="left" valign="top"><%=user.name %></td>
21
+ <td class="left" valign="top">
22
+ <%= user.groups.sort.map(&:name).join(', ') %> (<%= link_to "select", {:action => 'select_group', :id => user.id}, :id => "select-#{u user.login}" %>)
23
+ </td>
24
+ <td class="left" valign="top">
25
+ <%= link_to "edit", { :id => user.id, :action => 'edit'}, :id => "edit-#{u user.login}" %> |
26
+ <%= link_to "delete", {:action => 'destroy', :id => user.id}, {:confirm => "Warning : are you sure to delete this user ?", :method => 'delete', :id => "delete-#{u user.login}"} %>
27
+ </td>
28
+ </tr>
29
+ <% end %>
30
+ </tbody>
31
+ </table>
32
+ </td>
33
+ <td class="sep"> </td>
34
+ <td valign="top" align="right" width="210">
35
+ <%
36
+ action_name = 'create'
37
+ title='Add new user'
38
+ if @user.id
39
+ action_name = 'update'
40
+ title='Edit user'
41
+ end
42
+ %>
43
+ <% form_for :user, @user, :url => { :id => @user.id, :action => action_name}, :html => { :method => @user.id.nil?? :post : :put } do |f| %>
44
+ <table class="admintable" width="100%">
45
+ <tr>
46
+ <td class="left" valign="top"><h1><%= title %></h1></td>
47
+ </tr>
48
+ <tr>
49
+ <td class="left" valign="top"><%=t(:text_login)%>
50
+ <% if @user.id %>
51
+ <%= @user.login %>
52
+ <%= f.hidden_field :login %>
53
+
54
+ <% else %>
55
+ <br/><%= f.text_field :login, :size => 30, :maxLength => 40 %>
56
+ <% end %>
57
+ </td>
58
+ </tr>
59
+ <tr>
60
+ <td class="left" valign="top"><%=t(:text_name)%><br/><%= f.text_field :name, :size => 30, :maxLength => 200 %></td>
61
+ </tr>
62
+ <tr>
63
+ <td class="left" valign="top"><%=t(:text_password)%><br/><%= f.password_field :password, :size => 30, :maxLength => 50 %></td>
64
+ </tr>
65
+ <tr>
66
+ <td class="left" valign="top"><%=t(:text_confirm_password)%><br/><%= f.password_field :password_confirmation, :size => 30, :maxLength => 50 %></td>
67
+ </tr>
68
+ <tr>
69
+ <td class="left" nowrap="nowrap" valign="top" colspan="2">
70
+ <%= submit_tag @user.id.nil?? 'Create':'Update' %>
71
+ <%= link_to 'cancel', { :controller => 'users', :action => 'index'}, { :class => 'action' } %><br/>
72
+ </td>
73
+ </tr>
74
+
75
+ </table>
76
+ <% end %>
77
+ </td>
78
+ </tr>
79
+ </table>
80
+
81
+ <%= link_to "export",
82
+ url_for(:controller => 'api/rules', :action => 'index', :language => @profile.language, :profile => @profile.name,
83
+ :plugins => @plugins.join(','),
84
+ :status => @status, :searchtext => @searchtext, :priorities => @priorities.join(','), :categories => @categories.join(','),
85
+ :format => 'csv'),
86
+ :class => 'action' %>&nbsp;&nbsp;<%=t(:text_export)%>
87
+
88
+ <%= link_to_remote 'Add Event', {:url => { :controller => 'events', :action => "new", :rid => params['rid'] },
89
+ :update => "event_form"}, {:class => 'action'} %>
@@ -0,0 +1,20 @@
1
+ require 'helper'
2
+
3
+ class TestBaseExtractor < Test::Unit::TestCase
4
+ should "find a proper key for a given text/label" do
5
+ c = Object.new
6
+ def c.key_prefix; nil;end
7
+ def c.to_value(s); s ;end
8
+ c.extend ReadyForI18N::BaseExtractor
9
+ assert_equal('confirm_password', c.to_key('Confirm password:'))
10
+ end
11
+
12
+ should "work fine with prefix" do
13
+ c = Object.new
14
+ def c.key_prefix; 'label' ;end
15
+ def c.to_value(s); s ;end
16
+ c.extend ReadyForI18N::BaseExtractor
17
+ assert_equal('label_login', c.to_key('Login:'))
18
+ end
19
+
20
+ end
@@ -0,0 +1,22 @@
1
+ require 'helper'
2
+
3
+ class TestLabelExtractor < Test::Unit::TestCase
4
+ should "extract the label that need i18n from the erb view file" do
5
+ f = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
6
+ result = []
7
+ ReadyForI18N::LabelExtractor.new(f).extract{|k,v| result << v}
8
+ expected = %w{edit delete select export cancel} << "Add Event"
9
+ assert_same_elements(expected,result)
10
+ end
11
+
12
+ should "replace the label in helper with t method" do
13
+ source = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
14
+ target = File.join(File.dirname(__FILE__),'output','label.html.erb')
15
+ ReadyForI18N::LabelExtractor.new(source,target).extract
16
+ expected = %w{edit delete select export cancel add_event}
17
+ expected.each do |e|
18
+ assert(File.read(target).include?("t(:label_#{e})"), "should found t method with symbol")
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+
3
+ class TestLocaleDictionary < Test::Unit::TestCase
4
+ should "save the result hash to yaml file" do
5
+ target_path = File.join(File.dirname(__FILE__),'output')
6
+ dict = ReadyForI18N::LocaleDictionary.new
7
+ dict['login_key'] = 'Login:'
8
+ dict['label'] = 'OK'
9
+ dict['text'] = 'Please Confirm:'
10
+ dict.write_to target_path
11
+
12
+ result = YAML.load_file File.join(target_path,'en.yml')
13
+ assert_equal('Login:', result['en']['login_key'])
14
+ end
15
+
16
+ end
@@ -0,0 +1,21 @@
1
+ require 'helper'
2
+
3
+ class TestTextExtractor < Test::Unit::TestCase
4
+ should "extract the text that need i18n from the erb view file" do
5
+ f = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
6
+ expected = %w{Users Login Name Groups Operations Login: Name: Password: Export} << 'Confirm password:'
7
+ result = []
8
+ ReadyForI18N::TextExtractor.new(f).extract{|k,v| result << v}
9
+ assert_same_elements(expected,result)
10
+ end
11
+
12
+ should "replace the text in helper with t method" do
13
+ source = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
14
+ target = File.join(File.dirname(__FILE__),'output','text.html.erb')
15
+ ReadyForI18N::TextExtractor.new(source,target).extract
16
+ %w{Users Login Name Groups Operations Login: Name: Password: Export}.each do |e|
17
+ assert(File.read(target).include?("<%=t(:text_#{e.downcase.gsub(':','')})%>"), "should found t method with symbol")
18
+ end
19
+ end
20
+
21
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ready_for_i18n
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - zigzag
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-15 00:00:00 +08:00
13
+ default_executable: ready_for_i18n
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: " ready_for_i18n will help you extract visible hard-coded text from your ERB view files,\n then choose a proper key and replace them with the I18n.translate method like t(:login)\n"
26
+ email: zigzag.chen@gmail.com
27
+ executables:
28
+ - ready_for_i18n
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - bin/ready_for_i18n
42
+ - lib/base_extractor.rb
43
+ - lib/i18n_automator.rb
44
+ - lib/label_extractor.rb
45
+ - lib/locale_dictionary.rb
46
+ - lib/ready_for_i18n.rb
47
+ - lib/text_extractor.rb
48
+ - ready_for_i18n.gemspec
49
+ - test/fixtures/index.html.erb
50
+ - test/helper.rb
51
+ - test/output/en.yml
52
+ - test/output/label.html.erb
53
+ - test/output/text.html.erb
54
+ - test/test_base_extractor.rb
55
+ - test/test_label_extractor.rb
56
+ - test/test_locale_dictionary.rb
57
+ - test/test_text_extrator.rb
58
+ has_rdoc: true
59
+ homepage: http://github.com/zigzag/ready_for_i18n
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --charset=UTF-8
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.3.5
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: ready_for_i18n is a tool helping for the very first step of transfering your local Rails project to an i18n one.
86
+ test_files:
87
+ - test/helper.rb
88
+ - test/test_base_extractor.rb
89
+ - test/test_label_extractor.rb
90
+ - test/test_locale_dictionary.rb
91
+ - test/test_text_extrator.rb