translate-rails3-plus 0.0.1

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.
@@ -0,0 +1,396 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
6
+ <title><%= h(@page_title) %></title>
7
+
8
+ <%= translate_javascript_includes %>
9
+ <script type="text/javascript">
10
+ var source_ids = [];
11
+
12
+ function googleCallback(response) {
13
+ if (response.error) {
14
+ alert(response.error.message);
15
+ return;
16
+ }
17
+ var result_text = response.data.translations[0].translatedText.gsub(/__(.+)__/, function(match) {
18
+ return '{{' + match[1] + '}}';
19
+ });
20
+ var id = source_ids.shift();
21
+ if (id) {
22
+ Form.Element.setValue(id, result_text);
23
+ }
24
+ }
25
+
26
+ function getGoogleTranslation(id, text, from_language, to_language) {
27
+ source_ids.push(id);
28
+ text = text.replace(/\{\{/, '__').replace(/\}\}/, '__');
29
+ var s = document.createElement('script'), api_key = '<%= Translate.api_key %>';
30
+ s.type = 'text/javascript';
31
+ s.src = 'https://www.googleapis.com/language/translate/v2?key=' + api_key + '&source=' +
32
+ from_language + '&target=' + to_language + '&callback=googleCallback&q=' + text;
33
+ document.getElementsByTagName("head")[0].appendChild(s);
34
+ }
35
+
36
+ function bingCallback(text) {
37
+ var id = source_ids.shift();
38
+ if (text && id) {
39
+ var result_text = text.gsub(/__(.+)__/, function(match) {
40
+ return '{{' + match[1] + '}}';
41
+ });
42
+ Form.Element.setValue(id, result_text);
43
+ }
44
+ }
45
+
46
+ function getBingTranslation(id, text, from_language, to_language) {
47
+ source_ids.push(id);
48
+ text = text.replace(/\{\{/, '__').replace(/\}\}/, '__');
49
+ var s = document.createElement("script"), app_id = '<%= Translate.app_id %>';
50
+ s.type = 'text/javascript';
51
+ s.src = 'http://api.microsofttranslator.com/V2/Ajax.svc/Translate?oncomplete=bingCallback&appId=' +
52
+ app_id + '&from=' + from_language + '&to=' + to_language + '&text=' + text;
53
+ document.getElementsByTagName("head")[0].appendChild(s);
54
+ }
55
+
56
+ /*
57
+ prototypeUtils.js from http://jehiah.com/
58
+ Licensed under Creative Commons.
59
+ version 1.0 December 20 2005
60
+
61
+ Contains:
62
+ + Form.Element.setValue()
63
+ + unpackToForm()
64
+
65
+ */
66
+
67
+ /* Form.Element.setValue("fieldname/id","valueToSet") */
68
+ Form.Element.setValue = function(element,newValue) {
69
+ element_id = element;
70
+ element = $(element);
71
+ if (!element){element = document.getElementsByName(element_id)[0];}
72
+ if (!element){return false;}
73
+ var method = element.tagName.toLowerCase();
74
+ var parameter = Form.Element.SetSerializers[method](element,newValue);
75
+ }
76
+
77
+ Form.Element.SetSerializers = {
78
+ input: function(element,newValue) {
79
+ switch (element.type.toLowerCase()) {
80
+ case 'submit':
81
+ case 'hidden':
82
+ case 'password':
83
+ case 'text':
84
+ return Form.Element.SetSerializers.textarea(element,newValue);
85
+ case 'checkbox':
86
+ case 'radio':
87
+ return Form.Element.SetSerializers.inputSelector(element,newValue);
88
+ }
89
+ return false;
90
+ },
91
+
92
+ inputSelector: function(element,newValue) {
93
+ fields = document.getElementsByName(element.name);
94
+ for (var i=0;i<fields.length;i++){
95
+ if (fields[i].value == newValue){
96
+ fields[i].checked = true;
97
+ }
98
+ }
99
+ },
100
+
101
+ textarea: function(element,newValue) {
102
+ element.value = newValue;
103
+ },
104
+
105
+ select: function(element,newValue) {
106
+ var value = '', opt, index = element.selectedIndex;
107
+ for (var i=0;i< element.options.length;i++){
108
+ if (element.options[i].value == newValue){
109
+ element.selectedIndex = i;
110
+ return true;
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ function unpackToForm(data){
117
+ for (i in data){
118
+ Form.Element.setValue(i,data[i].toString());
119
+ }
120
+ }
121
+
122
+ </script>
123
+
124
+
125
+ <style type="text/css">
126
+ /*reset.css*/
127
+ /* v1.0 | 20080212 */
128
+ html, body, div, span, applet, object, iframe,
129
+ h1, h2, h3, h4, h5, h6, p, blockquote, pre,
130
+ a, abbr, acronym, address, big, cite, code,
131
+ del, dfn, em, font, img, ins, kbd, q, s, samp,
132
+ small, strike, strong, sub, sup, tt, var,
133
+ b, u, i, center,
134
+ dl, dt, dd, ol, ul, li,
135
+ fieldset, form, label, legend,
136
+ table, caption, tbody, tfoot, thead, tr, th, td {
137
+ margin: 0;
138
+ padding: 0;
139
+ border: 0;
140
+ outline: 0;
141
+ font-size: 100%;
142
+ vertical-align: baseline;
143
+ background: transparent;
144
+ }
145
+ body {
146
+ line-height: 1;
147
+ }
148
+ ol, ul {
149
+ list-style: none;
150
+ }
151
+ blockquote, q {
152
+ quotes: none;
153
+ }
154
+ blockquote:before, blockquote:after,
155
+ q:before, q:after {
156
+ content: '';
157
+ content: none;
158
+ }
159
+
160
+ /* remember to define focus styles! */
161
+ :focus {
162
+ outline: 0;
163
+ }
164
+
165
+ /* remember to highlight inserts somehow! */
166
+ ins {
167
+ text-decoration: none;
168
+ }
169
+ del {
170
+ text-decoration: line-through;
171
+ }
172
+
173
+ /* tables still need 'cellspacing="0"' in the markup */
174
+ table {
175
+ border-collapse: collapse;
176
+ border-spacing: 0;
177
+ }
178
+ /*clear fix*/
179
+ .clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}
180
+ .clearfix{display:inline-block;}
181
+ html[xmlns] .clearfix {
182
+ display: block;
183
+ }
184
+ * html .clearfix{height:1%;}
185
+ /*start layout*/
186
+ body{
187
+ background:#fff;
188
+ color:#333;
189
+ font-size:75%;
190
+ font-family:Arial;
191
+ margin:2em auto;
192
+ line-height:1.5em;
193
+ }
194
+ textarea,input,select{
195
+ font-family:Arial;
196
+ font-size:1em;
197
+ }
198
+ h1{
199
+ color:#d46021;
200
+ font-size:2em;
201
+ margin-bottom:0.5em;
202
+ }
203
+ h2{
204
+ text-align:left;
205
+ color:#d46021;
206
+ font-size:1.3em;
207
+ padding-left:0;
208
+ }
209
+ a{
210
+ color:#2158C7;
211
+ }
212
+ div#container{
213
+ width:960px;
214
+ margin:0 auto;
215
+ font-size:1em;
216
+ }
217
+ /*paging*/
218
+ div.paging{
219
+ margin-bottom:1em;
220
+ text-align:left;
221
+ }
222
+ div.paging div{
223
+ border:solid 1px red;
224
+ margin:1em 1em 0;
225
+ padding:0.5em;
226
+ border:solid 1px #d5d6d5;
227
+ background:#f1f1f1;
228
+ }
229
+ ul.paging{
230
+ display:inline-block;
231
+ }
232
+ ul.paging li{
233
+ display:block;
234
+ margin:0.2em 0;
235
+ float:left;
236
+ }
237
+ ul.paging li.selected a{
238
+ color:#fff;
239
+ background:#2158C7;
240
+ font-weight:bold;
241
+ padding:0.5em 0.7em;
242
+ }
243
+ ul.paging li a{
244
+ display:inline-block;
245
+ line-height:1em;
246
+ padding:0.5em 0.5em;
247
+ }
248
+ /*forms filter*/
249
+ fieldset{
250
+ padding:1em;
251
+ margin:1em;
252
+ border:solid 2px #d46021;
253
+ }
254
+ legend{
255
+ font-size:1.2em;
256
+ font-weight:bold;
257
+ padding:0 1em;
258
+ padding-bottom:0.5em;
259
+ }
260
+ label{
261
+ font-weight:bold;
262
+ }
263
+ fieldset span{padding-right:0.5em;}
264
+ div#show-sort label,
265
+ div#languages label,
266
+ div#filter-pattern label{
267
+ display:inline-block;
268
+ width:100px;
269
+ line-height:2em;
270
+ }
271
+ div#show-sort select,
272
+ div#languages select,
273
+ div#filter-pattern select{
274
+ width:120px;
275
+ margin-right:0.5em;
276
+ }
277
+ div#show-sort input.text-default,
278
+ div#languages input.text-default,
279
+ div#filter-pattern input.text-default{
280
+ width:200px;
281
+ }
282
+ p.hits{
283
+ margin-top:1em;
284
+ }
285
+ /*translation edit*/
286
+ div.translations{
287
+ margin:1em;
288
+ padding:1em;
289
+ border:solid 2px #d46021;
290
+ }
291
+ div.translations h2{
292
+ margin-bottom:1em;
293
+ }
294
+ p.translate{
295
+ background:red;
296
+ border:solid 1px #d5d6d5;
297
+ background:#f1f1f1;
298
+ margin:0.5em;
299
+ padding:0.7em 0.5em 0.5em 1.5em;
300
+ }
301
+ div.translation{
302
+ padding:1em;
303
+ border-bottom:solid 0.2em #d46021;
304
+ border-left: solid 0.1em #D46021;
305
+ margin:0 1em 1em 1.6em;
306
+ }
307
+ div.translation input, div.translation textarea{
308
+ width:98%;
309
+ margin:1em 0;
310
+ display:inline-block;
311
+ padding:0.3em;
312
+ }
313
+ div.translation textarea{
314
+ height:50px;
315
+ }
316
+ div.translation em strong{
317
+ color:#333;
318
+ padding-right:0.5em;
319
+ }
320
+ p.translation em{
321
+ display:block;
322
+ font-size:0.8333em;
323
+ }
324
+ div.translation a{
325
+ padding:1em;
326
+ }
327
+ div.translation input.btnDefault{
328
+ margin:0 0 1em;
329
+ width:auto;
330
+ }
331
+ .focus-text{
332
+ font-weight:bold;
333
+ }
334
+ div.selected{
335
+ margin:0 1em 1em 1em;
336
+ border-left:solid 0.6em #d46021;
337
+ border-right:solid 0.2em #d46021;
338
+ border-top:solid 0.2em #d46021;
339
+ background:#f1f1f1;
340
+ }
341
+ .display{display:block !important;}
342
+ /*feedback*/
343
+ div#notice, div#error {
344
+ font-size:1em;
345
+ margin:1em;
346
+ padding: 1em;
347
+ border: 1px solid red;
348
+ }
349
+ div#notice span, div#error span{
350
+ font-size:1.5em;
351
+ }
352
+
353
+ div#error {
354
+ background-color: #F3C6CC;
355
+ color: red;
356
+ }
357
+ div#notice {
358
+ border-color: #72A974;
359
+ color: #597B5C;
360
+ background-color: #BCFFBD;
361
+ }
362
+ .big-locale
363
+ {
364
+ font-size: 32px;
365
+ color: red;
366
+ }
367
+ </style>
368
+ <script type="text/javascript">
369
+ onload = function (){
370
+ $$("div.translation input, div.translation textarea").each(function (e){
371
+ Event.observe(e,'focus', function (elm){
372
+ this.up(1).down(".translation-text").addClassName("focus-text");
373
+ this.up(1).addClassName("selected");
374
+ });
375
+ Event.observe(e,'blur', function (elm,e){
376
+ this.up(1).down(".translation-text").removeClassName("focus-text");
377
+ this.up(1).removeClassName("selected");
378
+ });
379
+ });
380
+ }
381
+ </script>
382
+ </head>
383
+ <body>
384
+ <div id="container">
385
+ <% if @page_title -%><h1><%=h @page_title %></h1><% end -%>
386
+ <% [:notice, :error].each do |message| %>
387
+ <%if flash[message] %>
388
+ <div id="<%= message %>">
389
+ <span><%= h(flash[message]) if flash[message] %></span>
390
+ </div>
391
+ <% end %>
392
+ <% end %>
393
+ <%= yield %>
394
+ </div>
395
+ </body>
396
+ </html>
@@ -0,0 +1,42 @@
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
+ <p class="translation-text">
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><%= from_text_section %></li>
21
+ <p class="edit-form">
22
+ <% if n_lines > 1 %>
23
+ <%= text_area_tag("#{field_name}[#{index}]", to_text[index], :size => "#{line_size}x#{n_lines}", :id => "#{key}[#{index}]") %>
24
+ <% else %>
25
+ <%= text_field_tag("#{field_name}[#{index}]", to_text[index], :size => line_size, :id => "#{key}[#{index}]") %>
26
+ <% end %>
27
+ <%= translate_link("#{key}[#{index}]", from_text_section, @from_locale, @to_locale) %>
28
+ </p>
29
+ <% end %>
30
+ </ol>
31
+ </p>
32
+ <% end %>
33
+ <p>
34
+ <em>
35
+ <br/>
36
+ <strong>Key:</strong><%=h key %><br/>
37
+ <% if @files[key] %>
38
+ <strong>File:</strong><%= @files[key].join("<br/>") %>
39
+ <% end %>
40
+ </em>
41
+ </p>
42
+ </div>
@@ -0,0 +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 %>
@@ -0,0 +1,36 @@
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">
10
+ <% if from_text.present? %>
11
+ <p class="translation-text">
12
+ <% if from_text.starts_with?(" ") || from_text.ends_with?(" ")%>
13
+ <%= simple_format("&rarr;" + h(from_text) + "&larr;") %>
14
+ <% else %>
15
+ <%= simple_format(h(from_text)) %>
16
+ <% end %>
17
+ </p>
18
+ <% end %>
19
+ <p class="edit-form">
20
+ <% if n_lines > 1 %>
21
+ <%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key) %>
22
+ <% else %>
23
+ <%= text_field_tag(field_name, to_text, :size => line_size, :id => key) %>
24
+ <% end %>
25
+ </p>
26
+ <p>
27
+ <em>
28
+ <%= translate_link(key, from_text, @from_locale, @to_locale) %>
29
+ <br/>
30
+ <strong>Key:</strong><%=h key %><br/>
31
+ <% if @files[key] %>
32
+ <strong>File:</strong><%= @files[key].join("<br/>") %>
33
+ <% end %>
34
+ </em>
35
+ </p>
36
+ </div>
@@ -0,0 +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) 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
+ <%= submit_tag "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
+ <%= submit_tag "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 ADDED
@@ -0,0 +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
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'translate'