translate-rails3-plus 0.0.11 → 0.0.12
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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -20
- data/README.md +89 -89
- data/Rakefile +35 -35
- data/VERSION +1 -1
- data/app/controllers/translate_controller.rb +218 -218
- data/app/helpers/translate_helper.rb +53 -53
- data/app/views/layouts/translate.html.erb +495 -495
- data/app/views/translate/_array_form.html.erb +45 -45
- data/app/views/translate/_pagination.html.erb +24 -24
- data/app/views/translate/_string_form.html.erb +35 -35
- data/app/views/translate/index.html.erb +96 -96
- data/config/routes.rb +5 -5
- data/init.rb +1 -1
- data/lib/tasks/translate.rake +200 -200
- data/lib/translate.rb +17 -17
- data/lib/translate/file.rb +35 -35
- data/lib/translate/keys.rb +194 -194
- data/lib/translate/log.rb +35 -35
- data/lib/translate/routes.rb +11 -11
- data/lib/translate/storage.rb +28 -28
- data/spec/controllers/translate_controller_spec.rb +130 -130
- data/spec/file_spec.rb +54 -54
- data/spec/files/translate/app/models/article.rb +12 -12
- data/spec/files/translate/app/views/category.erb +1 -1
- data/spec/files/translate/app/views/category.html +1 -1
- data/spec/files/translate/app/views/category.html.erb +1 -1
- data/spec/files/translate/app/views/category.rhtml +5 -5
- data/spec/keys_spec.rb +179 -179
- data/spec/log_spec.rb +47 -47
- data/spec/spec_helper.rb +11 -11
- data/spec/storage_spec.rb +33 -33
- metadata +2 -2
@@ -1,45 +1,45 @@
|
|
1
|
-
<%
|
2
|
-
from_text = lookup(from_locale, key)
|
3
|
-
to_text = lookup(to_locale, key)
|
4
|
-
field_name = "key[#{key}]"
|
5
|
-
%>
|
6
|
-
|
7
|
-
<div class="translation">
|
8
|
-
<% if from_text.present? %>
|
9
|
-
|
10
|
-
<ol>
|
11
|
-
<% from_text.each_with_index do |from_text_section, index| %>
|
12
|
-
<%
|
13
|
-
from_text_section = from_text_section.to_s
|
14
|
-
line_size = 100
|
15
|
-
n_lines = n_lines(from_text_section, line_size)
|
16
|
-
# this is needed so the controller doesn't freak out when there is no translations found
|
17
|
-
# for this element yet...
|
18
|
-
to_text = Array.new if to_text.blank?
|
19
|
-
%>
|
20
|
-
<li class="single-translation">
|
21
|
-
<p class="translation-text"><%= from_text_section %></p>
|
22
|
-
<p class="edit-form" >
|
23
|
-
<% if n_lines > 1 %>
|
24
|
-
<%= text_area_tag("#{field_name}[#{index}]", to_text[index], :size => "#{line_size}x#{n_lines}", :id => "#{key}[#{index}]", :class=>'edit-field') %>
|
25
|
-
<% else %>
|
26
|
-
<%= text_field_tag("#{field_name}[#{index}]", to_text[index], :size => line_size, :id => "#{key}[#{index}]", :class=>'edit-field') %>
|
27
|
-
<% end %>
|
28
|
-
<%= translate_link("#{key}[#{index}]", from_text_section, @from_locale, @to_locale) %>
|
29
|
-
</p>
|
30
|
-
<div class="error-text"></div>
|
31
|
-
</li>
|
32
|
-
<% end %>
|
33
|
-
</ol>
|
34
|
-
|
35
|
-
<% end %>
|
36
|
-
<p>
|
37
|
-
<em>
|
38
|
-
<br/>
|
39
|
-
<strong>Key:</strong><%=h key %><br/>
|
40
|
-
<% if @files[key] %>
|
41
|
-
<strong>File:</strong><%= @files[key].join("<br/>") %>
|
42
|
-
<% end %>
|
43
|
-
</em>
|
44
|
-
</p>
|
45
|
-
</div>
|
1
|
+
<%
|
2
|
+
from_text = lookup(from_locale, key)
|
3
|
+
to_text = lookup(to_locale, key)
|
4
|
+
field_name = "key[#{key}]"
|
5
|
+
%>
|
6
|
+
|
7
|
+
<div class="translation">
|
8
|
+
<% if from_text.present? %>
|
9
|
+
|
10
|
+
<ol>
|
11
|
+
<% from_text.each_with_index do |from_text_section, index| %>
|
12
|
+
<%
|
13
|
+
from_text_section = from_text_section.to_s
|
14
|
+
line_size = 100
|
15
|
+
n_lines = n_lines(from_text_section, line_size)
|
16
|
+
# this is needed so the controller doesn't freak out when there is no translations found
|
17
|
+
# for this element yet...
|
18
|
+
to_text = Array.new if to_text.blank?
|
19
|
+
%>
|
20
|
+
<li class="single-translation">
|
21
|
+
<p class="translation-text"><%= from_text_section %></p>
|
22
|
+
<p class="edit-form" >
|
23
|
+
<% if n_lines > 1 %>
|
24
|
+
<%= text_area_tag("#{field_name}[#{index}]", to_text[index], :size => "#{line_size}x#{n_lines}", :id => "#{key}[#{index}]", :class=>'edit-field') %>
|
25
|
+
<% else %>
|
26
|
+
<%= text_field_tag("#{field_name}[#{index}]", to_text[index], :size => line_size, :id => "#{key}[#{index}]", :class=>'edit-field') %>
|
27
|
+
<% end %>
|
28
|
+
<%= translate_link("#{key}[#{index}]", from_text_section, @from_locale, @to_locale) %>
|
29
|
+
</p>
|
30
|
+
<div class="error-text"></div>
|
31
|
+
</li>
|
32
|
+
<% end %>
|
33
|
+
</ol>
|
34
|
+
|
35
|
+
<% end %>
|
36
|
+
<p>
|
37
|
+
<em>
|
38
|
+
<br/>
|
39
|
+
<strong>Key:</strong><%=h key %><br/>
|
40
|
+
<% if @files[key] %>
|
41
|
+
<strong>File:</strong><%= @files[key].join("<br/>") %>
|
42
|
+
<% end %>
|
43
|
+
</em>
|
44
|
+
</p>
|
45
|
+
</div>
|
@@ -1,24 +1,24 @@
|
|
1
|
-
<%
|
2
|
-
# Expects locals:
|
3
|
-
#
|
4
|
-
# total_entries
|
5
|
-
# per_page
|
6
|
-
|
7
|
-
n_pages = total_entries/per_page + (total_entries % per_page > 0 ? 1 : 0)
|
8
|
-
current_page = (params[:page] || 1).to_i
|
9
|
-
%>
|
10
|
-
|
11
|
-
<% if n_pages > 1 %>
|
12
|
-
<h2>Pages:</h2>
|
13
|
-
<div class="clearfix">
|
14
|
-
<ul class="paging">
|
15
|
-
<% (1..n_pages).each do |page_number| %>
|
16
|
-
<% if current_page == page_number %>
|
17
|
-
<li class="selected"><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}" ) %></li>
|
18
|
-
<% else %>
|
19
|
-
<li><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}") %></li>
|
20
|
-
<% end %>
|
21
|
-
<% end %>
|
22
|
-
</ul>
|
23
|
-
</div>
|
24
|
-
<% end %>
|
1
|
+
<%
|
2
|
+
# Expects locals:
|
3
|
+
#
|
4
|
+
# total_entries
|
5
|
+
# per_page
|
6
|
+
|
7
|
+
n_pages = total_entries/per_page + (total_entries % per_page > 0 ? 1 : 0)
|
8
|
+
current_page = (params[:page] || 1).to_i
|
9
|
+
%>
|
10
|
+
|
11
|
+
<% if n_pages > 1 %>
|
12
|
+
<h2>Pages:</h2>
|
13
|
+
<div class="clearfix">
|
14
|
+
<ul class="paging">
|
15
|
+
<% (1..n_pages).each do |page_number| %>
|
16
|
+
<% if current_page == page_number %>
|
17
|
+
<li class="selected"><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}" ) %></li>
|
18
|
+
<% else %>
|
19
|
+
<li><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}") %></li>
|
20
|
+
<% end %>
|
21
|
+
<% end %>
|
22
|
+
</ul>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
@@ -1,35 +1,35 @@
|
|
1
|
-
<%
|
2
|
-
from_text = lookup(from_locale, key)
|
3
|
-
to_text = lookup(to_locale, key)
|
4
|
-
line_size = 100
|
5
|
-
n_lines = n_lines(from_text, line_size)
|
6
|
-
field_name = "key[#{key}]"
|
7
|
-
%>
|
8
|
-
|
9
|
-
<div class="translation single-translation" >
|
10
|
-
<% if from_text.present? %>
|
11
|
-
<% if from_text.starts_with?(" ") || from_text.ends_with?(" ")%>
|
12
|
-
<%= simple_format("→" + h(from_text) + "←", :class => "translation-text" ) %>
|
13
|
-
<% else %>
|
14
|
-
<%= simple_format(h(from_text), :class => "translation-text") %>
|
15
|
-
<% end %>
|
16
|
-
<% end %>
|
17
|
-
<p class="edit-form">
|
18
|
-
<% if n_lines > 1 %>
|
19
|
-
<%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key, :class=>'edit-field') %>
|
20
|
-
<% else %>
|
21
|
-
<%= text_field_tag(field_name, to_text, :size => line_size, :id => key, :class=>'edit-field') %>
|
22
|
-
<% end %>
|
23
|
-
</p>
|
24
|
-
<div class="error-text"></div>
|
25
|
-
<p>
|
26
|
-
<em>
|
27
|
-
<%= translate_link(key, from_text, @from_locale, @to_locale) %>
|
28
|
-
<br/>
|
29
|
-
<strong>Key:</strong><%=h key %><br/>
|
30
|
-
<% if @files[key] %>
|
31
|
-
<strong>File:</strong><%= @files[key].join("<br/>") %>
|
32
|
-
<% end %>
|
33
|
-
</em>
|
34
|
-
</p>
|
35
|
-
</div>
|
1
|
+
<%
|
2
|
+
from_text = lookup(from_locale, key)
|
3
|
+
to_text = lookup(to_locale, key)
|
4
|
+
line_size = 100
|
5
|
+
n_lines = n_lines(from_text, line_size)
|
6
|
+
field_name = "key[#{key}]"
|
7
|
+
%>
|
8
|
+
|
9
|
+
<div class="translation single-translation" >
|
10
|
+
<% if from_text.present? %>
|
11
|
+
<% if from_text.starts_with?(" ") || from_text.ends_with?(" ")%>
|
12
|
+
<%= simple_format("→" + h(from_text) + "←", :class => "translation-text" ) %>
|
13
|
+
<% else %>
|
14
|
+
<%= simple_format(h(from_text), :class => "translation-text") %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<p class="edit-form">
|
18
|
+
<% if n_lines > 1 %>
|
19
|
+
<%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key, :class=>'edit-field') %>
|
20
|
+
<% else %>
|
21
|
+
<%= text_field_tag(field_name, to_text, :size => line_size, :id => key, :class=>'edit-field') %>
|
22
|
+
<% end %>
|
23
|
+
</p>
|
24
|
+
<div class="error-text"></div>
|
25
|
+
<p>
|
26
|
+
<em>
|
27
|
+
<%= translate_link(key, from_text, @from_locale, @to_locale) %>
|
28
|
+
<br/>
|
29
|
+
<strong>Key:</strong><%=h key %><br/>
|
30
|
+
<% if @files[key] %>
|
31
|
+
<strong>File:</strong><%= @files[key].join("<br/>") %>
|
32
|
+
<% end %>
|
33
|
+
</em>
|
34
|
+
</p>
|
35
|
+
</div>
|
@@ -1,96 +1,96 @@
|
|
1
|
-
<%
|
2
|
-
show_filters = ["all", "untranslated", "translated"]
|
3
|
-
show_filters << "changed" if @from_locale != @to_locale
|
4
|
-
%>
|
5
|
-
|
6
|
-
<fieldset>
|
7
|
-
<legend>Search filter</legend>
|
8
|
-
<div id="show-sort">
|
9
|
-
<p>
|
10
|
-
<label>Show:</label> <%= raw simple_filter(show_filters) %>
|
11
|
-
</p>
|
12
|
-
<p>
|
13
|
-
<label>Sort by:</label> <%= raw simple_filter(["key", "text"], 'sort_by') %>
|
14
|
-
</p>
|
15
|
-
</div>
|
16
|
-
<%= form_tag(params, :method => :get) do %>
|
17
|
-
<div id="languages">
|
18
|
-
<p>
|
19
|
-
<%= hidden_field_tag(:filter, params[:filter]) %>
|
20
|
-
<%= hidden_field_tag(:sort_by, params[:sort_by]) %>
|
21
|
-
<label>Translate from</label>
|
22
|
-
<%= select_tag(:from_locale, options_for_select(from_locales, @from_locale.to_sym)) %> <span>to</span>
|
23
|
-
<%= select_tag(:to_locale, options_for_select(to_locales, @to_locale.to_sym)) %>
|
24
|
-
<%= submit_tag "Display" %>
|
25
|
-
</p>
|
26
|
-
</div>
|
27
|
-
<div id="filter-pattern">
|
28
|
-
<p>
|
29
|
-
<label for="key_pattern_value">Key</label>
|
30
|
-
<%= select_tag(:key_type, options_for_select([["contains", 'contains'], ["starts with", 'starts_with']], params[:key_type])) %>
|
31
|
-
<%= text_field_tag(:key_pattern, params[:key_pattern], :size => 50, :id => "key_pattern_value", :class => "text-default") %>
|
32
|
-
</p>
|
33
|
-
<p>
|
34
|
-
<label for="text_pattern_value">Text</label>
|
35
|
-
<%= select_tag(:text_type, options_for_select(['contains', 'equals'], params[:text_type])) %>
|
36
|
-
<%= text_field_tag(:text_pattern, params[:text_pattern], :size => 50, :id => "text_pattern_value", :class => "text-default") %>
|
37
|
-
</p>
|
38
|
-
<p>
|
39
|
-
<label for="translated_text_pattern_value">Translated Text</label>
|
40
|
-
<%= select_tag(:translated_text_type, options_for_select(['contains', 'equals'], params[:translated_text_type])) %>
|
41
|
-
<%= text_field_tag(:translated_text_pattern, params[:translated_text_pattern], :size => 50, :id => "translated_text_pattern_value", :class => "text-default") %>
|
42
|
-
</p>
|
43
|
-
<p>
|
44
|
-
<%= submit_tag "Search" %>
|
45
|
-
<%= link_to "clear", params.merge({:text_pattern => nil, :translated_text_pattern => nil, :key_pattern => nil}) %>
|
46
|
-
</p>
|
47
|
-
</div>
|
48
|
-
<% end %>
|
49
|
-
<p class="hits">
|
50
|
-
Found <strong><%= @total_entries %></strong> messages
|
51
|
-
</p>
|
52
|
-
<p>
|
53
|
-
<%= link_to "Reload messages", translate_reload_path %>
|
54
|
-
</p>
|
55
|
-
</fieldset>
|
56
|
-
|
57
|
-
|
58
|
-
<div class="paging">
|
59
|
-
<%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
|
60
|
-
</div>
|
61
|
-
|
62
|
-
<% if @total_entries > 0 %>
|
63
|
-
<%= form_tag(translate_path, :name => 'translate_form') do %>
|
64
|
-
<div>
|
65
|
-
<%= hidden_field_tag(:filter, params[:filter], :id => "hid_filter") %>
|
66
|
-
<%= hidden_field_tag(:sort_by, params[:sort_by], :id => "hid_sort_by") %>
|
67
|
-
<%= hidden_field_tag(:key_type, params[:key_type], :id => "hid_key_type") %>
|
68
|
-
<%= hidden_field_tag(:key_pattern, params[:key_pattern], :id => "hid_key_pattern") %>
|
69
|
-
<%= hidden_field_tag(:text_type, params[:text_type], :id => "hid_text_type") %>
|
70
|
-
<%= hidden_field_tag(:text_pattern, params[:text_pattern], :id => "hid_text_pattern") %>
|
71
|
-
</div>
|
72
|
-
<div class="translations">
|
73
|
-
<h2>Translations from <span class='big-locale'><%= @from_locale %></span> to <span class='big-locale'><%= @to_locale %></span></h2>
|
74
|
-
<p class="translate">
|
75
|
-
<input onclick="testAndSave();" type="button" value="Save Translations">
|
76
|
-
</p>
|
77
|
-
<% @paginated_keys.each do |key| %>
|
78
|
-
<%=
|
79
|
-
from_text = lookup(@from_locale, key)
|
80
|
-
render (from_text.is_a?(Array) ? 'array_form' : 'string_form'), {
|
81
|
-
:from_locale => @from_locale,
|
82
|
-
:to_locale => @to_locale,
|
83
|
-
:key => key,
|
84
|
-
}
|
85
|
-
%>
|
86
|
-
<% end %>
|
87
|
-
<p class="translate">
|
88
|
-
<input onclick="testAndSave();" type="button" value="Save Translations">
|
89
|
-
</p>
|
90
|
-
</div>
|
91
|
-
<% end %>
|
92
|
-
<% end %>
|
93
|
-
|
94
|
-
<div class="paging">
|
95
|
-
<%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
|
96
|
-
</div>
|
1
|
+
<%
|
2
|
+
show_filters = ["all", "untranslated", "translated"]
|
3
|
+
show_filters << "changed" if @from_locale != @to_locale
|
4
|
+
%>
|
5
|
+
|
6
|
+
<fieldset>
|
7
|
+
<legend>Search filter</legend>
|
8
|
+
<div id="show-sort">
|
9
|
+
<p>
|
10
|
+
<label>Show:</label> <%= raw simple_filter(show_filters) %>
|
11
|
+
</p>
|
12
|
+
<p>
|
13
|
+
<label>Sort by:</label> <%= raw simple_filter(["key", "text"], 'sort_by') %>
|
14
|
+
</p>
|
15
|
+
</div>
|
16
|
+
<%= form_tag(params, :method => :get) do %>
|
17
|
+
<div id="languages">
|
18
|
+
<p>
|
19
|
+
<%= hidden_field_tag(:filter, params[:filter]) %>
|
20
|
+
<%= hidden_field_tag(:sort_by, params[:sort_by]) %>
|
21
|
+
<label>Translate from</label>
|
22
|
+
<%= select_tag(:from_locale, options_for_select(from_locales, @from_locale.to_sym)) %> <span>to</span>
|
23
|
+
<%= select_tag(:to_locale, options_for_select(to_locales, @to_locale.to_sym)) %>
|
24
|
+
<%= submit_tag "Display" %>
|
25
|
+
</p>
|
26
|
+
</div>
|
27
|
+
<div id="filter-pattern">
|
28
|
+
<p>
|
29
|
+
<label for="key_pattern_value">Key</label>
|
30
|
+
<%= select_tag(:key_type, options_for_select([["contains", 'contains'], ["starts with", 'starts_with']], params[:key_type])) %>
|
31
|
+
<%= text_field_tag(:key_pattern, params[:key_pattern], :size => 50, :id => "key_pattern_value", :class => "text-default") %>
|
32
|
+
</p>
|
33
|
+
<p>
|
34
|
+
<label for="text_pattern_value">Text</label>
|
35
|
+
<%= select_tag(:text_type, options_for_select(['contains', 'equals'], params[:text_type])) %>
|
36
|
+
<%= text_field_tag(:text_pattern, params[:text_pattern], :size => 50, :id => "text_pattern_value", :class => "text-default") %>
|
37
|
+
</p>
|
38
|
+
<p>
|
39
|
+
<label for="translated_text_pattern_value">Translated Text</label>
|
40
|
+
<%= select_tag(:translated_text_type, options_for_select(['contains', 'equals'], params[:translated_text_type])) %>
|
41
|
+
<%= text_field_tag(:translated_text_pattern, params[:translated_text_pattern], :size => 50, :id => "translated_text_pattern_value", :class => "text-default") %>
|
42
|
+
</p>
|
43
|
+
<p>
|
44
|
+
<%= submit_tag "Search" %>
|
45
|
+
<%= link_to "clear", params.merge({:text_pattern => nil, :translated_text_pattern => nil, :key_pattern => nil}) %>
|
46
|
+
</p>
|
47
|
+
</div>
|
48
|
+
<% end %>
|
49
|
+
<p class="hits">
|
50
|
+
Found <strong><%= @total_entries %></strong> messages
|
51
|
+
</p>
|
52
|
+
<p>
|
53
|
+
<%= link_to "Reload messages", translate_reload_path %>
|
54
|
+
</p>
|
55
|
+
</fieldset>
|
56
|
+
|
57
|
+
|
58
|
+
<div class="paging">
|
59
|
+
<%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
|
60
|
+
</div>
|
61
|
+
|
62
|
+
<% if @total_entries > 0 %>
|
63
|
+
<%= form_tag(translate_path, :name => 'translate_form') do %>
|
64
|
+
<div>
|
65
|
+
<%= hidden_field_tag(:filter, params[:filter], :id => "hid_filter") %>
|
66
|
+
<%= hidden_field_tag(:sort_by, params[:sort_by], :id => "hid_sort_by") %>
|
67
|
+
<%= hidden_field_tag(:key_type, params[:key_type], :id => "hid_key_type") %>
|
68
|
+
<%= hidden_field_tag(:key_pattern, params[:key_pattern], :id => "hid_key_pattern") %>
|
69
|
+
<%= hidden_field_tag(:text_type, params[:text_type], :id => "hid_text_type") %>
|
70
|
+
<%= hidden_field_tag(:text_pattern, params[:text_pattern], :id => "hid_text_pattern") %>
|
71
|
+
</div>
|
72
|
+
<div class="translations">
|
73
|
+
<h2>Translations from <span class='big-locale'><%= @from_locale %></span> to <span class='big-locale'><%= @to_locale %></span></h2>
|
74
|
+
<p class="translate">
|
75
|
+
<input onclick="testAndSave();" type="button" value="Save Translations">
|
76
|
+
</p>
|
77
|
+
<% @paginated_keys.each do |key| %>
|
78
|
+
<%=
|
79
|
+
from_text = lookup(@from_locale, key)
|
80
|
+
render (from_text.is_a?(Array) ? 'array_form' : 'string_form'), {
|
81
|
+
:from_locale => @from_locale,
|
82
|
+
:to_locale => @to_locale,
|
83
|
+
:key => key,
|
84
|
+
}
|
85
|
+
%>
|
86
|
+
<% end %>
|
87
|
+
<p class="translate">
|
88
|
+
<input onclick="testAndSave();" type="button" value="Save Translations">
|
89
|
+
</p>
|
90
|
+
</div>
|
91
|
+
<% end %>
|
92
|
+
<% end %>
|
93
|
+
|
94
|
+
<div class="paging">
|
95
|
+
<%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
|
96
|
+
</div>
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
Rails.application.routes.draw do
|
2
|
-
get 'translate' => 'translate#index', :as => :translate_list
|
3
|
-
post 'translate' => 'translate#translate', :as => :translate
|
4
|
-
get 'translate/reload' => 'translate#reload', :as => :translate_reload
|
5
|
-
end
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
get 'translate' => 'translate#index', :as => :translate_list
|
3
|
+
post 'translate' => 'translate#translate', :as => :translate
|
4
|
+
get 'translate/reload' => 'translate#reload', :as => :translate_reload
|
5
|
+
end
|
data/init.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'translate'
|
1
|
+
require 'translate'
|
data/lib/tasks/translate.rake
CHANGED
@@ -1,200 +1,200 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
class Hash
|
4
|
-
def deep_merge(other)
|
5
|
-
# deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
6
|
-
merger = proc { |key, v1, v2| (Hash === v1 && Hash === v2) ? v1.merge(v2, &merger) : v2 }
|
7
|
-
merge(other, &merger)
|
8
|
-
end
|
9
|
-
|
10
|
-
def set(keys, value)
|
11
|
-
key = keys.shift
|
12
|
-
if keys.empty?
|
13
|
-
self[key] = value
|
14
|
-
else
|
15
|
-
self[key] ||= {}
|
16
|
-
self[key].set keys, value
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
if ENV['SORT']
|
21
|
-
# copy of ruby's to_yaml method, prepending sort.
|
22
|
-
# before each so we get an ordered yaml file
|
23
|
-
def to_yaml( opts = {} )
|
24
|
-
YAML::quick_emit( self, opts ) do |out|
|
25
|
-
out.map( taguri, to_yaml_style ) do |map|
|
26
|
-
sort.each do |k, v| #<- Adding sort.
|
27
|
-
map.add( k, v )
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
namespace :translate do
|
36
|
-
desc "Show duplicate keys for locale LOCALE"
|
37
|
-
task :duplicates => :environment do
|
38
|
-
from_locale = I18n.default_locale
|
39
|
-
duplicates = Translate::Keys.new.duplicate_keys
|
40
|
-
|
41
|
-
messages = []
|
42
|
-
duplicates.each do |locale, keys|
|
43
|
-
keys.each do |key|
|
44
|
-
from_text = I18n.backend.send(:lookup, from_locale, key)
|
45
|
-
next if from_text.blank?
|
46
|
-
messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
if messages.present?
|
51
|
-
messages.each { |m| puts m }
|
52
|
-
else
|
53
|
-
puts "No duplicate keys"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
desc "Show untranslated keys for locale LOCALE"
|
58
|
-
task :untranslated => :environment do
|
59
|
-
from_locale = I18n.default_locale
|
60
|
-
untranslated = Translate::Keys.new.untranslated_keys
|
61
|
-
|
62
|
-
messages = []
|
63
|
-
untranslated.each do |locale, keys|
|
64
|
-
keys.each do |key|
|
65
|
-
from_text = I18n.backend.send(:lookup, from_locale, key)
|
66
|
-
next if from_text.blank?
|
67
|
-
messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
if messages.present?
|
72
|
-
messages.each { |m| puts m }
|
73
|
-
else
|
74
|
-
puts "No untranslated keys"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
desc "Show I18n keys that are missing in the config/locales/default_locale.yml YAML file"
|
79
|
-
task :missing => :environment do
|
80
|
-
missing = Translate::Keys.new.missing_keys.inject([]) do |keys, (key, filename)|
|
81
|
-
keys << "#{key} in \t #{filename} is missing"
|
82
|
-
end
|
83
|
-
puts missing.present? ? missing.join("\n") : "No missing translations in the default locale file"
|
84
|
-
end
|
85
|
-
|
86
|
-
desc "Remove all translation texts that are no longer present in the locale they were translated from"
|
87
|
-
task :remove_obsolete_keys => :environment do
|
88
|
-
I18n.backend.send(:init_translations)
|
89
|
-
master_locale = ENV['LOCALE'] || I18n.default_locale
|
90
|
-
Translate::Keys.translated_locales.each do |locale|
|
91
|
-
texts = {}
|
92
|
-
Translate::Keys.new.i18n_keys(locale).each do |key|
|
93
|
-
if I18n.backend.send(:lookup, master_locale, key).to_s.present?
|
94
|
-
texts[key] = I18n.backend.send(:lookup, locale, key)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
I18n.backend.send(:translations)[locale] = nil # Clear out all current translations
|
98
|
-
I18n.backend.store_translations(locale, Translate::Keys.to_deep_hash(texts))
|
99
|
-
Translate::Storage.new(locale).write_to_file
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
desc "Merge I18n keys from log/translations.yml into config/locales/*.yml (for use with the Rails I18n TextMate bundle)"
|
104
|
-
task :merge_keys => :environment do
|
105
|
-
I18n.backend.send(:init_translations)
|
106
|
-
new_translations = YAML::load(IO.read(File.join(Rails.root, "log", "translations.yml")))
|
107
|
-
raise("Can only merge in translations in single locale") if new_translations.keys.size > 1
|
108
|
-
locale = new_translations.keys.first
|
109
|
-
|
110
|
-
overwrites = false
|
111
|
-
Translate::Keys.to_shallow_hash(new_translations[locale]).keys.each do |key|
|
112
|
-
new_text = key.split(".").inject(new_translations[locale]) { |hash, sub_key| hash[sub_key] }
|
113
|
-
existing_text = I18n.backend.send(:lookup, locale.to_sym, key)
|
114
|
-
if existing_text && new_text != existing_text
|
115
|
-
puts "ERROR: key #{key} already exists with text '#{existing_text.inspect}' and would be overwritten by new text '#{new_text}'. " +
|
116
|
-
"Set environment variable OVERWRITE=1 if you really want to do this."
|
117
|
-
overwrites = true
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
if !overwrites || ENV['OVERWRITE']
|
122
|
-
I18n.backend.store_translations(locale, new_translations[locale])
|
123
|
-
Translate::Storage.new(locale).write_to_file
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
desc "Apply Google translate to auto translate all texts in locale ENV['FROM'] to locale ENV['TO']"
|
128
|
-
task :google => :environment do
|
129
|
-
raise "Please specify FROM and TO locales as environment variables" if ENV['FROM'].blank? || ENV['TO'].blank?
|
130
|
-
|
131
|
-
# Depends on httparty gem
|
132
|
-
# http://www.robbyonrails.com/articles/2009/03/16/httparty-goes-foreign
|
133
|
-
class GoogleApi
|
134
|
-
include HTTParty
|
135
|
-
base_uri 'ajax.googleapis.com'
|
136
|
-
def self.translate(string, to, from)
|
137
|
-
tries = 0
|
138
|
-
begin
|
139
|
-
get("/ajax/services/language/translate",
|
140
|
-
:query => {:langpair => "#{from}|#{to}", :q => string, :v => 1.0},
|
141
|
-
:format => :json)
|
142
|
-
rescue
|
143
|
-
tries += 1
|
144
|
-
puts("SLEEPING - retrying in 5...")
|
145
|
-
sleep(5)
|
146
|
-
retry if tries < 10
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
I18n.backend.send(:init_translations)
|
152
|
-
|
153
|
-
start_at = Time.now
|
154
|
-
translations = {}
|
155
|
-
Translate::Keys.new.i18n_keys(ENV['FROM']).each do |key|
|
156
|
-
from_text = I18n.backend.send(:lookup, ENV['FROM'], key).to_s
|
157
|
-
to_text = I18n.backend.send(:lookup, ENV['TO'], key)
|
158
|
-
if !from_text.blank? && to_text.blank?
|
159
|
-
print "#{key}: '#{from_text[0, 40]}' => "
|
160
|
-
if !translations[from_text]
|
161
|
-
response = GoogleApi.translate(from_text, ENV['TO'], ENV['FROM'])
|
162
|
-
translations[from_text] = response["responseData"] && response["responseData"]["translatedText"]
|
163
|
-
end
|
164
|
-
if !(translation = translations[from_text]).blank?
|
165
|
-
translation.gsub!(/\(\(([a-z_.]+)\)\)/i, '{{\1}}')
|
166
|
-
# Google translate sometimes replaces {{foobar}} with (()) foobar. We skip these
|
167
|
-
if translation !~ /\(\(\)\)/
|
168
|
-
puts "'#{translation[0, 40]}'"
|
169
|
-
I18n.backend.store_translations(ENV['TO'].to_sym, Translate::Keys.to_deep_hash({key => translation}))
|
170
|
-
else
|
171
|
-
puts "SKIPPING since interpolations were messed up: '#{translation[0,40]}'"
|
172
|
-
end
|
173
|
-
else
|
174
|
-
puts "NO TRANSLATION - #{response.inspect}"
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
puts "\nTime elapsed: #{(((Time.now - start_at) / 60) * 10).to_i / 10.to_f} minutes"
|
180
|
-
Translate::Storage.new(ENV['TO'].to_sym).write_to_file
|
181
|
-
end
|
182
|
-
|
183
|
-
desc "List keys that have changed I18n texts between YAML file ENV['FROM_FILE'] and YAML file ENV['TO_FILE']. Set ENV['VERBOSE'] to see changes"
|
184
|
-
task :changed => :environment do
|
185
|
-
from_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['FROM_FILE']).read)
|
186
|
-
to_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['TO_FILE']).read)
|
187
|
-
from_hash.each do |key, from_value|
|
188
|
-
if (to_value = to_hash[key]) && to_value != from_value
|
189
|
-
key_without_locale = key[/^[^.]+\.(.+)$/, 1]
|
190
|
-
if ENV['VERBOSE']
|
191
|
-
puts "KEY: #{key_without_locale}"
|
192
|
-
puts "FROM VALUE: '#{from_value}'"
|
193
|
-
puts "TO VALUE: '#{to_value}'"
|
194
|
-
else
|
195
|
-
puts key_without_locale
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
def deep_merge(other)
|
5
|
+
# deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
6
|
+
merger = proc { |key, v1, v2| (Hash === v1 && Hash === v2) ? v1.merge(v2, &merger) : v2 }
|
7
|
+
merge(other, &merger)
|
8
|
+
end
|
9
|
+
|
10
|
+
def set(keys, value)
|
11
|
+
key = keys.shift
|
12
|
+
if keys.empty?
|
13
|
+
self[key] = value
|
14
|
+
else
|
15
|
+
self[key] ||= {}
|
16
|
+
self[key].set keys, value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
if ENV['SORT']
|
21
|
+
# copy of ruby's to_yaml method, prepending sort.
|
22
|
+
# before each so we get an ordered yaml file
|
23
|
+
def to_yaml( opts = {} )
|
24
|
+
YAML::quick_emit( self, opts ) do |out|
|
25
|
+
out.map( taguri, to_yaml_style ) do |map|
|
26
|
+
sort.each do |k, v| #<- Adding sort.
|
27
|
+
map.add( k, v )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
namespace :translate do
|
36
|
+
desc "Show duplicate keys for locale LOCALE"
|
37
|
+
task :duplicates => :environment do
|
38
|
+
from_locale = I18n.default_locale
|
39
|
+
duplicates = Translate::Keys.new.duplicate_keys
|
40
|
+
|
41
|
+
messages = []
|
42
|
+
duplicates.each do |locale, keys|
|
43
|
+
keys.each do |key|
|
44
|
+
from_text = I18n.backend.send(:lookup, from_locale, key)
|
45
|
+
next if from_text.blank?
|
46
|
+
messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if messages.present?
|
51
|
+
messages.each { |m| puts m }
|
52
|
+
else
|
53
|
+
puts "No duplicate keys"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "Show untranslated keys for locale LOCALE"
|
58
|
+
task :untranslated => :environment do
|
59
|
+
from_locale = I18n.default_locale
|
60
|
+
untranslated = Translate::Keys.new.untranslated_keys
|
61
|
+
|
62
|
+
messages = []
|
63
|
+
untranslated.each do |locale, keys|
|
64
|
+
keys.each do |key|
|
65
|
+
from_text = I18n.backend.send(:lookup, from_locale, key)
|
66
|
+
next if from_text.blank?
|
67
|
+
messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
if messages.present?
|
72
|
+
messages.each { |m| puts m }
|
73
|
+
else
|
74
|
+
puts "No untranslated keys"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
desc "Show I18n keys that are missing in the config/locales/default_locale.yml YAML file"
|
79
|
+
task :missing => :environment do
|
80
|
+
missing = Translate::Keys.new.missing_keys.inject([]) do |keys, (key, filename)|
|
81
|
+
keys << "#{key} in \t #{filename} is missing"
|
82
|
+
end
|
83
|
+
puts missing.present? ? missing.join("\n") : "No missing translations in the default locale file"
|
84
|
+
end
|
85
|
+
|
86
|
+
desc "Remove all translation texts that are no longer present in the locale they were translated from"
|
87
|
+
task :remove_obsolete_keys => :environment do
|
88
|
+
I18n.backend.send(:init_translations)
|
89
|
+
master_locale = ENV['LOCALE'] || I18n.default_locale
|
90
|
+
Translate::Keys.translated_locales.each do |locale|
|
91
|
+
texts = {}
|
92
|
+
Translate::Keys.new.i18n_keys(locale).each do |key|
|
93
|
+
if I18n.backend.send(:lookup, master_locale, key).to_s.present?
|
94
|
+
texts[key] = I18n.backend.send(:lookup, locale, key)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
I18n.backend.send(:translations)[locale] = nil # Clear out all current translations
|
98
|
+
I18n.backend.store_translations(locale, Translate::Keys.to_deep_hash(texts))
|
99
|
+
Translate::Storage.new(locale).write_to_file
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
desc "Merge I18n keys from log/translations.yml into config/locales/*.yml (for use with the Rails I18n TextMate bundle)"
|
104
|
+
task :merge_keys => :environment do
|
105
|
+
I18n.backend.send(:init_translations)
|
106
|
+
new_translations = YAML::load(IO.read(File.join(Rails.root, "log", "translations.yml")))
|
107
|
+
raise("Can only merge in translations in single locale") if new_translations.keys.size > 1
|
108
|
+
locale = new_translations.keys.first
|
109
|
+
|
110
|
+
overwrites = false
|
111
|
+
Translate::Keys.to_shallow_hash(new_translations[locale]).keys.each do |key|
|
112
|
+
new_text = key.split(".").inject(new_translations[locale]) { |hash, sub_key| hash[sub_key] }
|
113
|
+
existing_text = I18n.backend.send(:lookup, locale.to_sym, key)
|
114
|
+
if existing_text && new_text != existing_text
|
115
|
+
puts "ERROR: key #{key} already exists with text '#{existing_text.inspect}' and would be overwritten by new text '#{new_text}'. " +
|
116
|
+
"Set environment variable OVERWRITE=1 if you really want to do this."
|
117
|
+
overwrites = true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
if !overwrites || ENV['OVERWRITE']
|
122
|
+
I18n.backend.store_translations(locale, new_translations[locale])
|
123
|
+
Translate::Storage.new(locale).write_to_file
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
desc "Apply Google translate to auto translate all texts in locale ENV['FROM'] to locale ENV['TO']"
|
128
|
+
task :google => :environment do
|
129
|
+
raise "Please specify FROM and TO locales as environment variables" if ENV['FROM'].blank? || ENV['TO'].blank?
|
130
|
+
|
131
|
+
# Depends on httparty gem
|
132
|
+
# http://www.robbyonrails.com/articles/2009/03/16/httparty-goes-foreign
|
133
|
+
class GoogleApi
|
134
|
+
include HTTParty
|
135
|
+
base_uri 'ajax.googleapis.com'
|
136
|
+
def self.translate(string, to, from)
|
137
|
+
tries = 0
|
138
|
+
begin
|
139
|
+
get("/ajax/services/language/translate",
|
140
|
+
:query => {:langpair => "#{from}|#{to}", :q => string, :v => 1.0},
|
141
|
+
:format => :json)
|
142
|
+
rescue
|
143
|
+
tries += 1
|
144
|
+
puts("SLEEPING - retrying in 5...")
|
145
|
+
sleep(5)
|
146
|
+
retry if tries < 10
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
I18n.backend.send(:init_translations)
|
152
|
+
|
153
|
+
start_at = Time.now
|
154
|
+
translations = {}
|
155
|
+
Translate::Keys.new.i18n_keys(ENV['FROM']).each do |key|
|
156
|
+
from_text = I18n.backend.send(:lookup, ENV['FROM'], key).to_s
|
157
|
+
to_text = I18n.backend.send(:lookup, ENV['TO'], key)
|
158
|
+
if !from_text.blank? && to_text.blank?
|
159
|
+
print "#{key}: '#{from_text[0, 40]}' => "
|
160
|
+
if !translations[from_text]
|
161
|
+
response = GoogleApi.translate(from_text, ENV['TO'], ENV['FROM'])
|
162
|
+
translations[from_text] = response["responseData"] && response["responseData"]["translatedText"]
|
163
|
+
end
|
164
|
+
if !(translation = translations[from_text]).blank?
|
165
|
+
translation.gsub!(/\(\(([a-z_.]+)\)\)/i, '{{\1}}')
|
166
|
+
# Google translate sometimes replaces {{foobar}} with (()) foobar. We skip these
|
167
|
+
if translation !~ /\(\(\)\)/
|
168
|
+
puts "'#{translation[0, 40]}'"
|
169
|
+
I18n.backend.store_translations(ENV['TO'].to_sym, Translate::Keys.to_deep_hash({key => translation}))
|
170
|
+
else
|
171
|
+
puts "SKIPPING since interpolations were messed up: '#{translation[0,40]}'"
|
172
|
+
end
|
173
|
+
else
|
174
|
+
puts "NO TRANSLATION - #{response.inspect}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
puts "\nTime elapsed: #{(((Time.now - start_at) / 60) * 10).to_i / 10.to_f} minutes"
|
180
|
+
Translate::Storage.new(ENV['TO'].to_sym).write_to_file
|
181
|
+
end
|
182
|
+
|
183
|
+
desc "List keys that have changed I18n texts between YAML file ENV['FROM_FILE'] and YAML file ENV['TO_FILE']. Set ENV['VERBOSE'] to see changes"
|
184
|
+
task :changed => :environment do
|
185
|
+
from_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['FROM_FILE']).read)
|
186
|
+
to_hash = Translate::Keys.to_shallow_hash(Translate::File.new(ENV['TO_FILE']).read)
|
187
|
+
from_hash.each do |key, from_value|
|
188
|
+
if (to_value = to_hash[key]) && to_value != from_value
|
189
|
+
key_without_locale = key[/^[^.]+\.(.+)$/, 1]
|
190
|
+
if ENV['VERBOSE']
|
191
|
+
puts "KEY: #{key_without_locale}"
|
192
|
+
puts "FROM VALUE: '#{from_value}'"
|
193
|
+
puts "TO VALUE: '#{to_value}'"
|
194
|
+
else
|
195
|
+
puts key_without_locale
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|