translate-rails3 0.2.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +9 -6
- data/Rakefile +6 -5
- data/VERSION +1 -1
- data/app/controllers/translate_controller.rb +63 -27
- data/app/helpers/translate_helper.rb +26 -21
- data/app/views/layouts/translate.html.erb +349 -245
- data/app/views/translate/_array_form.html.erb +13 -10
- data/app/views/translate/_string_form.html.erb +9 -6
- data/app/views/translate/index.html.erb +10 -6
- data/lib/tasks/translate.rake +22 -0
- data/lib/translate.rb +1 -1
- data/lib/translate/keys.rb +9 -0
- data/translate-rails3.gemspec +10 -9
- metadata +38 -43
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: be316db288564b0402ea25c9a893925879036248
|
4
|
+
data.tar.gz: e0a2200895b4c73b58f28c40c1e31fe097f9b325
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 77ff1b9a66bae72c2d21a926dcee31eb212019e61202ff1d1d7368c7ff3b195680a6ddd83b2d6b908621ec56467f1670dc70067b9c2f9fe30590bfcb6cd4fc6b
|
7
|
+
data.tar.gz: 8c7496dd20eab5a679bc8cb918785c0c31b0821bab38340f38aa9aba235b95fa6bbc4bf38adc39282286b6cabfb38dda8c80e9752a96c95dbe3889764f9faf99
|
data/README.md
CHANGED
@@ -21,12 +21,13 @@ Rake Tasks
|
|
21
21
|
|
22
22
|
In addition to the web UI this plugin adds the following rake tasks:
|
23
23
|
|
24
|
-
translate:untranslated
|
25
|
-
translate:missing
|
26
|
-
translate:remove_obsolete_keys
|
27
|
-
translate:merge_keys
|
28
|
-
translate:google
|
29
|
-
translate:changed
|
24
|
+
translate:untranslated
|
25
|
+
translate:missing
|
26
|
+
translate:remove_obsolete_keys
|
27
|
+
translate:merge_keys
|
28
|
+
translate:google
|
29
|
+
translate:changed
|
30
|
+
translate:duplicates
|
30
31
|
|
31
32
|
The missing task shows you any I18n keys in your code that do not have translations in the YAML file for your default locale, i.e. config/locales/sv.yml.
|
32
33
|
|
@@ -37,6 +38,8 @@ The google task is used for auto translating from one locale to another using Go
|
|
37
38
|
|
38
39
|
The changed rake task can show you between one YAML file to another which keys have had their texts changed.
|
39
40
|
|
41
|
+
The duplicates task can show you strings that are the same in both locales.
|
42
|
+
|
40
43
|
Installation
|
41
44
|
------------
|
42
45
|
|
data/Rakefile
CHANGED
@@ -20,12 +20,13 @@ The plugin has been tested only with the simple I18n backend that ships
|
|
20
20
|
with Rails.
|
21
21
|
I18n texts are read from and written to YAML files under config/locales.
|
22
22
|
|
23
|
-
This gem is a fork of
|
24
|
-
|
23
|
+
This gem is a fork of https://github.com/romanbsd/translate.
|
24
|
+
From the original https://github.com/mynewsdesk/translate
|
25
|
+
which also includes work from this fork: https://github.com/milann/translate
|
25
26
|
EOF
|
26
|
-
gem.email = '
|
27
|
-
gem.homepage = 'https://github.com/
|
28
|
-
gem.authors = ['Peter Marklund', 'Milan Novota', 'Roman Shterenzon']
|
27
|
+
gem.email = 'gsmedley@kanayo.com'
|
28
|
+
gem.homepage = 'https://github.com/gsmedley/translate'
|
29
|
+
gem.authors = ['Peter Marklund', 'Milan Novota', 'Roman Shterenzon', 'Garth Smedley']
|
29
30
|
gem.add_dependency 'ya2yaml', '~> 0.30' # For UTF-8 support in YAML
|
30
31
|
end
|
31
32
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -12,10 +12,12 @@ class TranslateController < ActionController::Base
|
|
12
12
|
initialize_keys
|
13
13
|
filter_by_key_pattern
|
14
14
|
filter_by_text_pattern
|
15
|
+
filter_by_translated_text_pattern
|
15
16
|
filter_by_translated_or_changed
|
16
17
|
sort_keys
|
17
18
|
paginate_keys
|
18
19
|
@total_entries = @keys.size
|
20
|
+
@page_title = page_title
|
19
21
|
end
|
20
22
|
|
21
23
|
# POST /translate
|
@@ -26,7 +28,7 @@ class TranslateController < ActionController::Base
|
|
26
28
|
Translate::Log.new(@from_locale, @to_locale, params[:key].keys).write_to_file
|
27
29
|
force_init_translations # Force reload from YAML file
|
28
30
|
flash[:notice] = "Translations stored"
|
29
|
-
redirect_to params.slice(:filter, :sort_by, :key_type, :key_pattern, :text_type, :text_pattern
|
31
|
+
redirect_to translate_path params.slice(:filter, :sort_by, :key_type, :key_pattern, :text_type, :text_pattern, :translated_text_type, :translated_text_pattern)
|
30
32
|
end
|
31
33
|
|
32
34
|
# GET /translate/reload
|
@@ -47,11 +49,32 @@ class TranslateController < ActionController::Base
|
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
52
|
+
def page_title
|
53
|
+
"Translate"
|
54
|
+
end
|
55
|
+
|
50
56
|
def lookup(locale, key)
|
51
57
|
I18n.backend.send(:lookup, locale, key)
|
52
58
|
end
|
53
59
|
helper_method :lookup
|
54
60
|
|
61
|
+
def from_locales
|
62
|
+
# Attempt to get the list of locale from configuration
|
63
|
+
from_loc = Rails.application.config.from_locales if Rails.application.config.respond_to?(:from_locales)
|
64
|
+
return I18n.available_locales if from_loc.blank?
|
65
|
+
raise StandardError, "from_locale expected to be an array" if from_loc.class != Array
|
66
|
+
from_loc
|
67
|
+
end
|
68
|
+
helper_method :from_locales
|
69
|
+
|
70
|
+
def to_locales
|
71
|
+
to_loc = Rails.application.config.to_locales if Rails.application.config.respond_to?(:to_locales)
|
72
|
+
return I18n.available_locales if to_loc.blank?
|
73
|
+
raise StandardError, "to_locales expected to be an array" if to_loc.class != Array
|
74
|
+
to_loc
|
75
|
+
end
|
76
|
+
helper_method :to_locales
|
77
|
+
|
55
78
|
def filter_by_translated_or_changed
|
56
79
|
params[:filter] ||= 'all'
|
57
80
|
return if params[:filter] == 'all'
|
@@ -62,7 +85,16 @@ class TranslateController < ActionController::Base
|
|
62
85
|
when 'translated'
|
63
86
|
lookup(@to_locale, key).blank?
|
64
87
|
when 'changed'
|
65
|
-
|
88
|
+
lookup(@from_locale, key).to_s == lookup(@to_locale, key).to_s
|
89
|
+
when 'list_changed'
|
90
|
+
fr = lookup(@from_locale, key).to_s.squish
|
91
|
+
to = lookup(@to_locale, key).to_s.squish
|
92
|
+
if fr.downcase != to.downcase
|
93
|
+
p '--'
|
94
|
+
p 'c:' + fr
|
95
|
+
p 'g:' + to
|
96
|
+
end
|
97
|
+
fr.downcase == to.downcase
|
66
98
|
else
|
67
99
|
raise "Unknown filter '#{params[:filter]}'"
|
68
100
|
end
|
@@ -97,6 +129,20 @@ class TranslateController < ActionController::Base
|
|
97
129
|
end
|
98
130
|
end
|
99
131
|
|
132
|
+
def filter_by_translated_text_pattern
|
133
|
+
return if params[:translated_text_pattern].blank?
|
134
|
+
@keys.reject! do |key|
|
135
|
+
case params[:translated_text_type]
|
136
|
+
when 'contains' then
|
137
|
+
!lookup(@to_locale, key).present? || !lookup(@to_locale, key).to_s.downcase.index(params[:translated_text_pattern].downcase)
|
138
|
+
when 'equals' then
|
139
|
+
!lookup(@to_locale, key).present? || lookup(@to_locale, key).to_s.downcase != params[:translated_text_pattern].downcase
|
140
|
+
else
|
141
|
+
raise "Unknown translated_text_type '#{params[:translated_text_type]}'"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
100
146
|
def sort_keys
|
101
147
|
params[:sort_by] ||= "key"
|
102
148
|
case params[:sort_by]
|
@@ -143,39 +189,29 @@ class TranslateController < ActionController::Base
|
|
143
189
|
I18n.default_locale
|
144
190
|
end
|
145
191
|
|
192
|
+
def default_to_locale
|
193
|
+
:en
|
194
|
+
end
|
195
|
+
|
146
196
|
def set_locale
|
147
197
|
session[:from_locale] ||= default_locale
|
148
|
-
session[:to_locale] ||=
|
198
|
+
session[:to_locale] ||= default_to_locale
|
149
199
|
session[:from_locale] = params[:from_locale] if params[:from_locale].present?
|
150
200
|
session[:to_locale] = params[:to_locale] if params[:to_locale].present?
|
151
201
|
@from_locale = session[:from_locale].to_sym
|
152
202
|
@to_locale = session[:to_locale].to_sym
|
153
203
|
end
|
154
204
|
|
155
|
-
def
|
156
|
-
|
157
|
-
@old_from_text = {}
|
158
|
-
text = key.split(".").inject(log_hash) do |hash, k|
|
159
|
-
hash ? hash[k] : nil
|
160
|
-
end
|
161
|
-
@old_from_text[key] = text
|
162
|
-
end
|
163
|
-
helper_method :old_from_text
|
205
|
+
def process_array_parameters(parameter)
|
206
|
+
reconstructed_hash = Hash.new
|
164
207
|
|
165
|
-
|
166
|
-
|
208
|
+
parameter.each do |key, value|
|
209
|
+
if value.is_a?(String)
|
210
|
+
reconstructed_hash[key] = value
|
211
|
+
elsif value.is_a?(Hash)
|
212
|
+
reconstructed_hash[key] = Translate::Keys.arraylize(value)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
reconstructed_hash
|
167
216
|
end
|
168
|
-
|
169
|
-
def process_array_parameters(parameter)
|
170
|
-
reconstructed_hash = Hash.new
|
171
|
-
|
172
|
-
parameter.each do |key, value|
|
173
|
-
if value.is_a?(String)
|
174
|
-
reconstructed_hash[key] = value
|
175
|
-
elsif value.is_a?(Hash)
|
176
|
-
reconstructed_hash[key] = Translate::Keys.arraylize(value)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
reconstructed_hash
|
180
|
-
end
|
181
217
|
end
|
@@ -1,20 +1,5 @@
|
|
1
1
|
module TranslateHelper
|
2
2
|
|
3
|
-
def from_locales
|
4
|
-
# Attempt to get the list of locale from configuration
|
5
|
-
from_loc = Rails.application.config.from_locales if Rails.application.config.respond_to?(:from_locales)
|
6
|
-
return I18n.available_locales if from_loc.blank?
|
7
|
-
raise StandardError, "from_locale expected to be an array" if from_loc.class != Array
|
8
|
-
from_loc
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_locales
|
12
|
-
to_loc = Rails.application.config.to_locales if Rails.application.config.respond_to?(:to_locales)
|
13
|
-
return I18n.available_locales if to_loc.blank?
|
14
|
-
raise StandardError, "to_locales expected to be an array" if to_loc.class != Array
|
15
|
-
to_loc
|
16
|
-
end
|
17
|
-
|
18
3
|
def simple_filter(labels, param_name = 'filter', selected_value = nil)
|
19
4
|
selected_value ||= params[param_name]
|
20
5
|
filter = []
|
@@ -47,15 +32,11 @@ module TranslateHelper
|
|
47
32
|
end
|
48
33
|
|
49
34
|
def translate_javascript_includes
|
50
|
-
sources = []
|
51
35
|
if File.exists?(File.join(Rails.root, "public", "javascripts", "prototype.js"))
|
52
|
-
|
36
|
+
javascript_include_tag("prototype.js")
|
53
37
|
else
|
54
|
-
|
38
|
+
javascript_include_tag("http://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js")
|
55
39
|
end
|
56
|
-
sources.map do |src|
|
57
|
-
%Q{<script src="#{src}" type="text/javascript"></script>}
|
58
|
-
end.join("\n").html_safe
|
59
40
|
end
|
60
41
|
|
61
42
|
def translate_link(key, text, from, to)
|
@@ -69,4 +50,28 @@ module TranslateHelper
|
|
69
50
|
return nil unless method
|
70
51
|
link_to_function 'Auto Translate', "#{method}('#{key}', \"#{escape_javascript(text)}\", '#{from}', '#{to}')", :style => 'padding: 0; margin: 0;'
|
71
52
|
end
|
53
|
+
|
54
|
+
# copy/paste of missing function, because it was deprecated in Rails 4.1
|
55
|
+
def button_to_function(name, function=nil, html_options={})
|
56
|
+
message = "button_to_function is deprecated and will be removed from Rails 4.1. We recommend using Unobtrusive JavaScript instead. " +
|
57
|
+
"See http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript"
|
58
|
+
ActiveSupport::Deprecation.warn message
|
59
|
+
|
60
|
+
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
|
61
|
+
|
62
|
+
tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
|
63
|
+
end
|
64
|
+
|
65
|
+
# copy/paste of missing function, because it was deprecated in Rails 4.1
|
66
|
+
def link_to_function(name, function, html_options={})
|
67
|
+
message = "link_to_function is deprecated and will be removed from Rails 4.1. We recommend using Unobtrusive JavaScript instead. " +
|
68
|
+
"See http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript"
|
69
|
+
ActiveSupport::Deprecation.warn message
|
70
|
+
|
71
|
+
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
|
72
|
+
href = html_options[:href] || '#'
|
73
|
+
|
74
|
+
content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
|
75
|
+
end
|
76
|
+
|
72
77
|
end
|
@@ -7,6 +7,51 @@
|
|
7
7
|
|
8
8
|
<%= translate_javascript_includes %>
|
9
9
|
<script type="text/javascript">
|
10
|
+
|
11
|
+
// Return elements which are in A but not in arg0 through argn
|
12
|
+
Array.prototype.diff =
|
13
|
+
function() {
|
14
|
+
var a1 = this;
|
15
|
+
var a = a2 = null;
|
16
|
+
var n = 0;
|
17
|
+
while(n < arguments.length) {
|
18
|
+
a = [];
|
19
|
+
a2 = arguments[n];
|
20
|
+
var l = a1.length;
|
21
|
+
var l2 = a2.length;
|
22
|
+
var diff = true;
|
23
|
+
for(var i=0; i<l; i++) {
|
24
|
+
for(var j=0; j<l2; j++) {
|
25
|
+
if (a1[i] === a2[j]) {
|
26
|
+
diff = false;
|
27
|
+
break;
|
28
|
+
}
|
29
|
+
}
|
30
|
+
diff ? a.push(a1[i]) : diff = true;
|
31
|
+
}
|
32
|
+
a1 = a;
|
33
|
+
n++;
|
34
|
+
}
|
35
|
+
return a.unique();
|
36
|
+
};
|
37
|
+
|
38
|
+
// Return new array with duplicate values removed
|
39
|
+
Array.prototype.unique =
|
40
|
+
function() {
|
41
|
+
var a = [];
|
42
|
+
var l = this.length;
|
43
|
+
for(var i=0; i<l; i++) {
|
44
|
+
for(var j=i+1; j<l; j++) {
|
45
|
+
// If this[i] is found later in the array
|
46
|
+
if (this[i] === this[j])
|
47
|
+
j = ++i;
|
48
|
+
}
|
49
|
+
a.push(this[i]);
|
50
|
+
}
|
51
|
+
return a;
|
52
|
+
};
|
53
|
+
|
54
|
+
|
10
55
|
var source_ids = [];
|
11
56
|
|
12
57
|
function googleCallback(response) {
|
@@ -53,6 +98,50 @@
|
|
53
98
|
document.getElementsByTagName("head")[0].appendChild(s);
|
54
99
|
}
|
55
100
|
|
101
|
+
function checkErrors()
|
102
|
+
{
|
103
|
+
var errors = []
|
104
|
+
$$('.translation-error').each(function(item) {
|
105
|
+
item.removeClassName("translation-error")
|
106
|
+
item.select('.error-text')[0].innerHTML = ""
|
107
|
+
});
|
108
|
+
|
109
|
+
$$('.single-translation').each(function(item) {
|
110
|
+
var val = item.select('.edit-field')[0].value
|
111
|
+
if( !val.blank() )
|
112
|
+
{
|
113
|
+
var patt1=/%\{[^\{\}]*\}/g;
|
114
|
+
var val_subs = val.match(patt1)
|
115
|
+
var key = item.select('.translation-text')[0].innerHTML
|
116
|
+
var key_subs = key.match(patt1)
|
117
|
+
if( val_subs == null ){ val_subs = [] }
|
118
|
+
if( key_subs == null ){ key_subs = [] }
|
119
|
+
if( val_subs.sort().join('') != key_subs.sort().join('') )
|
120
|
+
{
|
121
|
+
missing_subs = key_subs.diff( val_subs )
|
122
|
+
item.addClassName("translation-error");
|
123
|
+
errors.push( item )
|
124
|
+
item.select('.error-text')[0].innerHTML = "Missing substitution strings: " + missing_subs.join(', ')
|
125
|
+
}
|
126
|
+
}
|
127
|
+
});
|
128
|
+
return errors
|
129
|
+
}
|
130
|
+
|
131
|
+
function testAndSave()
|
132
|
+
{
|
133
|
+
var errors = checkErrors()
|
134
|
+
|
135
|
+
if( errors.length == 0 )
|
136
|
+
{
|
137
|
+
document.forms["translate_form"].submit();
|
138
|
+
}
|
139
|
+
else
|
140
|
+
{
|
141
|
+
alert( "Some translations have errors. Please review and correct errors before saving.")
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
56
145
|
/*
|
57
146
|
prototypeUtils.js from http://jehiah.com/
|
58
147
|
Licensed under Creative Commons.
|
@@ -123,232 +212,232 @@
|
|
123
212
|
|
124
213
|
|
125
214
|
<style type="text/css">
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
215
|
+
/*reset.css*/
|
216
|
+
/* v1.0 | 20080212 */
|
217
|
+
html, body, div, span, applet, object, iframe,
|
218
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
219
|
+
a, abbr, acronym, address, big, cite, code,
|
220
|
+
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
221
|
+
small, strike, strong, sub, sup, tt, var,
|
222
|
+
b, u, i, center,
|
223
|
+
dl, dt, dd, ol, ul, li,
|
224
|
+
fieldset, form, label, legend,
|
225
|
+
table, caption, tbody, tfoot, thead, tr, th, td {
|
226
|
+
margin: 0;
|
227
|
+
padding: 0;
|
228
|
+
border: 0;
|
229
|
+
outline: 0;
|
230
|
+
font-size: 100%;
|
231
|
+
vertical-align: baseline;
|
232
|
+
background: transparent;
|
233
|
+
}
|
234
|
+
body {
|
235
|
+
line-height: 1;
|
236
|
+
}
|
237
|
+
ol, ul {
|
238
|
+
list-style: none;
|
239
|
+
}
|
240
|
+
blockquote, q {
|
241
|
+
quotes: none;
|
242
|
+
}
|
243
|
+
blockquote:before, blockquote:after,
|
244
|
+
q:before, q:after {
|
245
|
+
content: '';
|
246
|
+
content: none;
|
247
|
+
}
|
159
248
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
249
|
+
/* remember to define focus styles! */
|
250
|
+
:focus {
|
251
|
+
outline: 0;
|
252
|
+
}
|
164
253
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
254
|
+
/* remember to highlight inserts somehow! */
|
255
|
+
ins {
|
256
|
+
text-decoration: none;
|
257
|
+
}
|
258
|
+
del {
|
259
|
+
text-decoration: line-through;
|
260
|
+
}
|
172
261
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
262
|
+
/* tables still need 'cellspacing="0"' in the markup */
|
263
|
+
table {
|
264
|
+
border-collapse: collapse;
|
265
|
+
border-spacing: 0;
|
266
|
+
}
|
267
|
+
/*clear fix*/
|
268
|
+
.clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}
|
269
|
+
.clearfix{display:inline-block;}
|
270
|
+
html[xmlns] .clearfix {
|
271
|
+
display: block;
|
272
|
+
}
|
273
|
+
* html .clearfix{height:1%;}
|
274
|
+
/*start layout*/
|
275
|
+
body{
|
276
|
+
background:#fff;
|
277
|
+
color:#333;
|
278
|
+
font-size:75%;
|
279
|
+
font-family:Arial;
|
280
|
+
margin:2em auto;
|
281
|
+
line-height:1.5em;
|
282
|
+
}
|
283
|
+
textarea,input,select{
|
284
|
+
font-family:Arial;
|
285
|
+
font-size:1em;
|
286
|
+
}
|
287
|
+
h1{
|
288
|
+
color:#d46021;
|
289
|
+
font-size:2em;
|
290
|
+
margin-bottom:0.5em;
|
291
|
+
}
|
292
|
+
h2{
|
293
|
+
text-align:left;
|
294
|
+
color:#d46021;
|
295
|
+
font-size:1.3em;
|
296
|
+
padding-left:0;
|
297
|
+
}
|
298
|
+
a{
|
299
|
+
color:#2158C7;
|
300
|
+
}
|
301
|
+
div#container{
|
302
|
+
width:960px;
|
303
|
+
margin:0 auto;
|
304
|
+
font-size:1em;
|
305
|
+
}
|
306
|
+
/*paging*/
|
307
|
+
div.paging{
|
308
|
+
margin-bottom:1em;
|
309
|
+
text-align:left;
|
310
|
+
}
|
311
|
+
div.paging div{
|
312
|
+
border:solid 1px red;
|
313
|
+
margin:1em 1em 0;
|
314
|
+
padding:0.5em;
|
315
|
+
border:solid 1px #d5d6d5;
|
316
|
+
background:#f1f1f1;
|
317
|
+
}
|
318
|
+
ul.paging{
|
319
|
+
display:inline-block;
|
320
|
+
}
|
321
|
+
ul.paging li{
|
322
|
+
display:block;
|
323
|
+
margin:0.2em 0;
|
324
|
+
float:left;
|
325
|
+
}
|
326
|
+
ul.paging li.selected a{
|
327
|
+
color:#fff;
|
328
|
+
background:#2158C7;
|
329
|
+
font-weight:bold;
|
330
|
+
padding:0.5em 0.7em;
|
331
|
+
}
|
332
|
+
ul.paging li a{
|
333
|
+
display:inline-block;
|
334
|
+
line-height:1em;
|
335
|
+
padding:0.5em 0.5em;
|
336
|
+
}
|
337
|
+
/*forms filter*/
|
338
|
+
fieldset{
|
339
|
+
padding:1em;
|
340
|
+
margin:1em;
|
341
|
+
border:solid 2px #d46021;
|
342
|
+
}
|
343
|
+
legend{
|
344
|
+
font-size:1.2em;
|
345
|
+
font-weight:bold;
|
346
|
+
padding:0 1em;
|
347
|
+
padding-bottom:0.5em;
|
348
|
+
}
|
349
|
+
label{
|
350
|
+
font-weight:bold;
|
351
|
+
}
|
352
|
+
fieldset span{padding-right:0.5em;}
|
353
|
+
div#show-sort label,
|
354
|
+
div#languages label,
|
355
|
+
div#filter-pattern label{
|
356
|
+
display:inline-block;
|
357
|
+
width:100px;
|
358
|
+
line-height:2em;
|
359
|
+
}
|
360
|
+
div#show-sort select,
|
361
|
+
div#languages select,
|
362
|
+
div#filter-pattern select{
|
363
|
+
width:120px;
|
364
|
+
margin-right:0.5em;
|
365
|
+
}
|
366
|
+
div#show-sort input.text-default,
|
367
|
+
div#languages input.text-default,
|
368
|
+
div#filter-pattern input.text-default{
|
369
|
+
width:200px;
|
370
|
+
}
|
371
|
+
p.hits{
|
372
|
+
margin-top:1em;
|
373
|
+
}
|
374
|
+
/*translation edit*/
|
375
|
+
div.translations{
|
376
|
+
margin:1em;
|
377
|
+
padding:1em;
|
378
|
+
border:solid 2px #d46021;
|
379
|
+
}
|
380
|
+
div.translations h2{
|
381
|
+
margin-bottom:1em;
|
382
|
+
}
|
383
|
+
p.translate{
|
384
|
+
background:red;
|
385
|
+
border:solid 1px #d5d6d5;
|
386
|
+
background:#f1f1f1;
|
387
|
+
margin:0.5em;
|
388
|
+
padding:0.7em 0.5em 0.5em 1.5em;
|
389
|
+
}
|
390
|
+
div.translation{
|
391
|
+
padding: 11px;
|
392
|
+
border-bottom:solid 1px #d46021;
|
393
|
+
border-left: solid 1px #D46021;
|
394
|
+
margin:14px 12px 12px 19px;
|
395
|
+
}
|
396
|
+
div.translation input, div.translation textarea{
|
397
|
+
width:98%;
|
398
|
+
margin:1em 0;
|
399
|
+
display:inline-block;
|
400
|
+
padding:0.3em;
|
401
|
+
}
|
402
|
+
div.translation textarea{
|
403
|
+
height:50px;
|
404
|
+
}
|
405
|
+
div.translation em strong{
|
406
|
+
color:#333;
|
407
|
+
padding-right:0.5em;
|
408
|
+
}
|
409
|
+
p.translation em{
|
410
|
+
display:block;
|
411
|
+
font-size:0.8333em;
|
412
|
+
}
|
413
|
+
div.translation a{
|
414
|
+
padding:1em;
|
415
|
+
}
|
416
|
+
div.translation input.btnDefault{
|
417
|
+
margin:0 0 1em;
|
418
|
+
width:auto;
|
419
|
+
}
|
420
|
+
.focus-text{
|
421
|
+
font-weight:bold;
|
422
|
+
}
|
423
|
+
div.selected{
|
424
|
+
margin:12px 10px 12px 12px;
|
425
|
+
border-left:solid 8px #d46021;
|
426
|
+
border-right:solid 2px #d46021;
|
427
|
+
border-top:solid 2px #d46021;
|
428
|
+
background:#f1f1f1;
|
429
|
+
}
|
430
|
+
.display{display:block !important;}
|
431
|
+
/*feedback*/
|
432
|
+
div#notice, div#error {
|
433
|
+
font-size:1em;
|
434
|
+
margin:1em;
|
346
435
|
padding: 1em;
|
347
|
-
|
436
|
+
border: 1px solid red;
|
437
|
+
}
|
438
|
+
div#notice span, div#error span{
|
439
|
+
font-size:1.5em;
|
348
440
|
}
|
349
|
-
div#notice span, div#error span{
|
350
|
-
font-size:1.5em;
|
351
|
-
}
|
352
441
|
|
353
442
|
div#error {
|
354
443
|
background-color: #F3C6CC;
|
@@ -358,34 +447,49 @@
|
|
358
447
|
border-color: #72A974;
|
359
448
|
color: #597B5C;
|
360
449
|
background-color: #BCFFBD;
|
450
|
+
}
|
451
|
+
.translation-error .edit-field
|
452
|
+
{
|
453
|
+
border: 1px solid red;
|
454
|
+
}
|
455
|
+
.error-text
|
456
|
+
{
|
457
|
+
color: red;
|
458
|
+
}
|
459
|
+
.big-locale
|
460
|
+
{
|
461
|
+
font-size: 32px;
|
462
|
+
color: red;
|
361
463
|
}
|
362
464
|
</style>
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
465
|
+
<script type="text/javascript">
|
466
|
+
onload = function (){
|
467
|
+
$$("div.translation input, div.translation textarea").each(function (e){
|
468
|
+
Event.observe(e,'focus', function (elm){
|
469
|
+
this.up(".single-translation").down(".translation-text").addClassName("focus-text");
|
470
|
+
this.up(".translation").addClassName("selected");
|
471
|
+
});
|
472
|
+
Event.observe(e,'blur', function (elm,e){
|
473
|
+
this.up(".single-translation").down(".translation-text").removeClassName("focus-text");
|
474
|
+
this.up(".translation").removeClassName("selected");
|
475
|
+
});
|
476
|
+
});
|
477
|
+
|
478
|
+
checkErrors()
|
479
|
+
}
|
480
|
+
</script>
|
377
481
|
</head>
|
378
482
|
<body>
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
483
|
+
<div id="container">
|
484
|
+
<% if @page_title -%><h1><%=h @page_title %></h1><% end -%>
|
485
|
+
<% [:notice, :error].each do |message| %>
|
486
|
+
<%if flash[message] %>
|
487
|
+
<div id="<%= message %>">
|
488
|
+
<span><%= h(flash[message]) if flash[message] %></span>
|
489
|
+
</div>
|
490
|
+
<% end %>
|
491
|
+
<% end %>
|
492
|
+
<%= yield %>
|
389
493
|
</div>
|
390
494
|
</body>
|
391
495
|
</html>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
<div class="translation">
|
8
8
|
<% if from_text.present? %>
|
9
|
-
|
9
|
+
|
10
10
|
<ol>
|
11
11
|
<% from_text.each_with_index do |from_text_section, index| %>
|
12
12
|
<%
|
@@ -17,18 +17,21 @@
|
|
17
17
|
# for this element yet...
|
18
18
|
to_text = Array.new if to_text.blank?
|
19
19
|
%>
|
20
|
-
<li
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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) %>
|
28
29
|
</p>
|
30
|
+
<div class="error-text"></div>
|
31
|
+
</li>
|
29
32
|
<% end %>
|
30
33
|
</ol>
|
31
|
-
|
34
|
+
|
32
35
|
<% end %>
|
33
36
|
<p>
|
34
37
|
<em>
|
@@ -6,19 +6,22 @@
|
|
6
6
|
field_name = "key[#{key}]"
|
7
7
|
%>
|
8
8
|
|
9
|
-
<div class="translation">
|
9
|
+
<div class="translation single-translation" >
|
10
10
|
<% if from_text.present? %>
|
11
|
-
|
12
|
-
|
13
|
-
|
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 %>
|
14
16
|
<% end %>
|
15
17
|
<p class="edit-form">
|
16
18
|
<% if n_lines > 1 %>
|
17
|
-
<%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key) %>
|
19
|
+
<%= text_area_tag(field_name, to_text, :size => "#{line_size}x#{n_lines}", :id => key, :class=>'edit-field') %>
|
18
20
|
<% else %>
|
19
|
-
<%= text_field_tag(field_name, to_text, :size => line_size, :id => key) %>
|
21
|
+
<%= text_field_tag(field_name, to_text, :size => line_size, :id => key, :class=>'edit-field') %>
|
20
22
|
<% end %>
|
21
23
|
</p>
|
24
|
+
<div class="error-text"></div>
|
22
25
|
<p>
|
23
26
|
<em>
|
24
27
|
<%= translate_link(key, from_text, @from_locale, @to_locale) %>
|
@@ -1,5 +1,4 @@
|
|
1
1
|
<%
|
2
|
-
@page_title = "Translate"
|
3
2
|
show_filters = ["all", "untranslated", "translated"]
|
4
3
|
show_filters << "changed" if @from_locale != @to_locale
|
5
4
|
%>
|
@@ -36,9 +35,14 @@ show_filters << "changed" if @from_locale != @to_locale
|
|
36
35
|
<%= select_tag(:text_type, options_for_select(['contains', 'equals'], params[:text_type])) %>
|
37
36
|
<%= text_field_tag(:text_pattern, params[:text_pattern], :size => 50, :id => "text_pattern_value", :class => "text-default") %>
|
38
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>
|
39
43
|
<p>
|
40
44
|
<%= submit_tag "Search" %>
|
41
|
-
<%= link_to "clear", params.merge({:text_pattern => nil, :key_pattern => nil}) %>
|
45
|
+
<%= link_to "clear", params.merge({:text_pattern => nil, :translated_text_pattern => nil, :key_pattern => nil}) %>
|
42
46
|
</p>
|
43
47
|
</div>
|
44
48
|
<% end %>
|
@@ -56,7 +60,7 @@ show_filters << "changed" if @from_locale != @to_locale
|
|
56
60
|
</div>
|
57
61
|
|
58
62
|
<% if @total_entries > 0 %>
|
59
|
-
<%= form_tag(translate_path) do %>
|
63
|
+
<%= form_tag(translate_path, :name => 'translate_form') do %>
|
60
64
|
<div>
|
61
65
|
<%= hidden_field_tag(:filter, params[:filter], :id => "hid_filter") %>
|
62
66
|
<%= hidden_field_tag(:sort_by, params[:sort_by], :id => "hid_sort_by") %>
|
@@ -66,9 +70,9 @@ show_filters << "changed" if @from_locale != @to_locale
|
|
66
70
|
<%= hidden_field_tag(:text_pattern, params[:text_pattern], :id => "hid_text_pattern") %>
|
67
71
|
</div>
|
68
72
|
<div class="translations">
|
69
|
-
<h2>Translations from
|
73
|
+
<h2>Translations from <span class='big-locale'><%= @from_locale %></span> to <span class='big-locale'><%= @to_locale %></span></h2>
|
70
74
|
<p class="translate">
|
71
|
-
<%=
|
75
|
+
<%= button_to_function 'Save Translations', 'testAndSave()' %>
|
72
76
|
</p>
|
73
77
|
<% @paginated_keys.each do |key| %>
|
74
78
|
<%=
|
@@ -81,7 +85,7 @@ show_filters << "changed" if @from_locale != @to_locale
|
|
81
85
|
%>
|
82
86
|
<% end %>
|
83
87
|
<p class="translate">
|
84
|
-
<%=
|
88
|
+
<%= button_to_function 'Save Translations', 'testAndSave()' %>
|
85
89
|
</p>
|
86
90
|
</div>
|
87
91
|
<% end %>
|
data/lib/tasks/translate.rake
CHANGED
@@ -33,6 +33,27 @@ class Hash
|
|
33
33
|
end
|
34
34
|
|
35
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
|
+
|
36
57
|
desc "Show untranslated keys for locale LOCALE"
|
37
58
|
task :untranslated => :environment do
|
38
59
|
from_locale = I18n.default_locale
|
@@ -42,6 +63,7 @@ namespace :translate do
|
|
42
63
|
untranslated.each do |locale, keys|
|
43
64
|
keys.each do |key|
|
44
65
|
from_text = I18n.backend.send(:lookup, from_locale, key)
|
66
|
+
next if from_text.blank?
|
45
67
|
messages << "#{locale}.#{key} (#{from_locale}.#{key}='#{from_text}')"
|
46
68
|
end
|
47
69
|
end
|
data/lib/translate.rb
CHANGED
data/lib/translate/keys.rb
CHANGED
@@ -26,6 +26,15 @@ class Translate::Keys
|
|
26
26
|
Translate::Keys.to_shallow_hash(I18n.backend.send(:translations)[locale.to_sym]).keys.sort
|
27
27
|
end
|
28
28
|
|
29
|
+
def duplicate_keys
|
30
|
+
Translate::Keys.translated_locales.inject({}) do |missing, locale|
|
31
|
+
missing[locale] = i18n_keys(I18n.default_locale).map do |key|
|
32
|
+
I18n.backend.send(:lookup, locale, key) == I18n.backend.send(:lookup, I18n.default_locale, key) ? key : nil
|
33
|
+
end.compact
|
34
|
+
missing
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
29
38
|
def untranslated_keys
|
30
39
|
Translate::Keys.translated_locales.inject({}) do |missing, locale|
|
31
40
|
missing[locale] = i18n_keys(I18n.default_locale).map do |key|
|
data/translate-rails3.gemspec
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: translate-rails3 0.4.0 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "translate-rails3"
|
8
|
-
s.version = "0.
|
9
|
+
s.version = "0.4.0"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
s.
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Peter Marklund", "Milan Novota", "Roman Shterenzon", "Garth Smedley"]
|
14
|
+
s.date = "2015-01-15"
|
15
|
+
s.description = "This plugin provides a web interface for translating Rails I18n texts\n(requires Rails 3.0 or higher) from one locale to another.\nThe plugin has been tested only with the simple I18n backend that ships\nwith Rails.\nI18n texts are read from and written to YAML files under config/locales.\n\nThis gem is a fork of https://github.com/romanbsd/translate.\nFrom the original https://github.com/mynewsdesk/translate\nwhich also includes work from this fork: https://github.com/milann/translate\n"
|
16
|
+
s.email = "gsmedley@kanayo.com"
|
15
17
|
s.extra_rdoc_files = [
|
16
18
|
"README.md"
|
17
19
|
]
|
@@ -50,13 +52,12 @@ Gem::Specification.new do |s|
|
|
50
52
|
"spec/storage_spec.rb",
|
51
53
|
"translate-rails3.gemspec"
|
52
54
|
]
|
53
|
-
s.homepage = "https://github.com/
|
54
|
-
s.
|
55
|
-
s.rubygems_version = "1.8.15"
|
55
|
+
s.homepage = "https://github.com/gsmedley/translate"
|
56
|
+
s.rubygems_version = "2.4.3"
|
56
57
|
s.summary = "Newsdesk translate plugin for Rails 3"
|
57
58
|
|
58
59
|
if s.respond_to? :specification_version then
|
59
|
-
s.specification_version =
|
60
|
+
s.specification_version = 4
|
60
61
|
|
61
62
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
62
63
|
s.add_runtime_dependency(%q<ya2yaml>, ["~> 0.30"])
|
metadata
CHANGED
@@ -1,48 +1,48 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: translate-rails3
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.2.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- Peter Marklund
|
9
8
|
- Milan Novota
|
10
9
|
- Roman Shterenzon
|
10
|
+
- Garth Smedley
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
date: 2015-01-15 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
18
17
|
name: ya2yaml
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: "0.30"
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0.30'
|
26
23
|
type: :runtime
|
27
|
-
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.30'
|
28
30
|
description: |
|
29
31
|
This plugin provides a web interface for translating Rails I18n texts
|
30
32
|
(requires Rails 3.0 or higher) from one locale to another.
|
31
33
|
The plugin has been tested only with the simple I18n backend that ships
|
32
34
|
with Rails.
|
33
35
|
I18n texts are read from and written to YAML files under config/locales.
|
34
|
-
|
35
|
-
This gem is a fork of the original https://github.com/mynewsdesk/translate
|
36
|
-
and also includes work from this fork: https://github.com/milann/translate
|
37
36
|
|
38
|
-
|
37
|
+
This gem is a fork of https://github.com/romanbsd/translate.
|
38
|
+
From the original https://github.com/mynewsdesk/translate
|
39
|
+
which also includes work from this fork: https://github.com/milann/translate
|
40
|
+
email: gsmedley@kanayo.com
|
39
41
|
executables: []
|
40
|
-
|
41
42
|
extensions: []
|
42
|
-
|
43
|
-
extra_rdoc_files:
|
43
|
+
extra_rdoc_files:
|
44
44
|
- README.md
|
45
|
-
files:
|
45
|
+
files:
|
46
46
|
- MIT-LICENSE
|
47
47
|
- README.md
|
48
48
|
- Rakefile
|
@@ -76,32 +76,27 @@ files:
|
|
76
76
|
- spec/spec_helper.rb
|
77
77
|
- spec/storage_spec.rb
|
78
78
|
- translate-rails3.gemspec
|
79
|
-
homepage: https://github.com/
|
79
|
+
homepage: https://github.com/gsmedley/translate
|
80
80
|
licenses: []
|
81
|
-
|
81
|
+
metadata: {}
|
82
82
|
post_install_message:
|
83
83
|
rdoc_options: []
|
84
|
-
|
85
|
-
require_paths:
|
84
|
+
require_paths:
|
86
85
|
- lib
|
87
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
-
|
89
|
-
requirements:
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
90
88
|
- - ">="
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version:
|
93
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
-
|
95
|
-
requirements:
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
96
93
|
- - ">="
|
97
|
-
- !ruby/object:Gem::Version
|
98
|
-
version:
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
99
96
|
requirements: []
|
100
|
-
|
101
97
|
rubyforge_project:
|
102
|
-
rubygems_version:
|
98
|
+
rubygems_version: 2.4.3
|
103
99
|
signing_key:
|
104
|
-
specification_version:
|
100
|
+
specification_version: 4
|
105
101
|
summary: Newsdesk translate plugin for Rails 3
|
106
102
|
test_files: []
|
107
|
-
|