rails-i18nterface 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +22 -0
- data/README.md +109 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/rails_i18nterface/application.js +8 -0
- data/app/assets/javascripts/rails_i18nterface/base.js +62 -0
- data/app/assets/javascripts/rails_i18nterface/ender.js +3260 -0
- data/app/assets/javascripts/rails_i18nterface/ender.min.js +45 -0
- data/app/assets/stylesheets/rails_i18nterface/application.css +450 -0
- data/app/controllers/rails_i18nterface/application_controller.rb +4 -0
- data/app/controllers/rails_i18nterface/translate_controller.rb +255 -0
- data/app/helpers/rails_i18nterface/application_helper.rb +4 -0
- data/app/helpers/rails_i18nterface/translate_helper.rb +74 -0
- data/app/models/translation.rb +4 -0
- data/app/views/layouts/rails_i18nterface/translate.html.erb +13 -0
- data/app/views/rails_i18nterface/translate/_namespaces.html.erb +1 -0
- data/app/views/rails_i18nterface/translate/_pagination.html.erb +18 -0
- data/app/views/rails_i18nterface/translate/index.html.erb +132 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20110921112044_create_translations.rb +18 -0
- data/lib/rails-i18nterface.rb +8 -0
- data/lib/rails-i18nterface/engine.rb +7 -0
- data/lib/rails-i18nterface/file.rb +35 -0
- data/lib/rails-i18nterface/keys.rb +192 -0
- data/lib/rails-i18nterface/log.rb +35 -0
- data/lib/rails-i18nterface/storage.rb +29 -0
- data/lib/rails-i18nterface/version.rb +3 -0
- data/lib/tasks/rails-i18nterface.rake +4 -0
- data/spec/controllers/translate_controller_spec.rb +135 -0
- data/spec/internal/app/assets/javascripts/application.js +2 -0
- data/spec/internal/app/assets/stylesheets/application.css +3 -0
- data/spec/internal/app/controllers/application_controller.rb +4 -0
- data/spec/internal/app/models/article.rb +11 -0
- data/spec/internal/app/views/application/index.html.erb +5 -0
- data/spec/internal/app/views/categories/category.erb +1 -0
- data/spec/internal/app/views/categories/category.html +1 -0
- data/spec/internal/app/views/categories/category.html.erb +1 -0
- data/spec/internal/app/views/categories/category.rhtml +5 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +4 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +3 -0
- data/spec/internal/log/test.log +521 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/file_spec.rb +53 -0
- data/spec/lib/keys_spec.rb +179 -0
- data/spec/lib/log_spec.rb +46 -0
- data/spec/lib/storage_spec.rb +33 -0
- data/spec/requests/search_spec.rb +62 -0
- data/spec/spec_helper.rb +37 -0
- metadata +200 -0
@@ -0,0 +1,255 @@
|
|
1
|
+
module RailsI18nterface
|
2
|
+
class TranslateController < RailsI18nterface::ApplicationController
|
3
|
+
|
4
|
+
before_filter :init_translations
|
5
|
+
before_filter :set_locale
|
6
|
+
|
7
|
+
def index
|
8
|
+
@dbvalues = {}
|
9
|
+
initialize_keys
|
10
|
+
load_db_translations
|
11
|
+
@deep_keys = RailsI18nterface::Keys.to_deep_hash(@keys)
|
12
|
+
filter_by_key_pattern
|
13
|
+
filter_by_text_pattern
|
14
|
+
filter_by_translated_or_changed
|
15
|
+
sort_keys
|
16
|
+
paginate_keys
|
17
|
+
@total_entries = @keys.size
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_db_translations
|
21
|
+
@versions = {}
|
22
|
+
@dbvalues = {@to_locale => {}}
|
23
|
+
(Translation.where(:locale => @to_locale) || []).each { |translation|
|
24
|
+
@versions[translation.key] = translation.updated_at.to_i
|
25
|
+
@dbvalues[@to_locale][translation.key] = translation.value
|
26
|
+
@keys << translation.key
|
27
|
+
}
|
28
|
+
@keys.uniq!
|
29
|
+
end
|
30
|
+
|
31
|
+
def export
|
32
|
+
locale = params[:locale].to_sym
|
33
|
+
keys = {locale => I18n.backend.send(:translations)[locale] || {}}
|
34
|
+
Translation.where(:locale => @to_locale).each { |translation|
|
35
|
+
next if translation.value == ''
|
36
|
+
next if !translation.value
|
37
|
+
set_nested(keys[locale], translation.key.split("."), translation.value)
|
38
|
+
}
|
39
|
+
remove_blanks keys
|
40
|
+
yaml = keys_to_yaml(deep_stringify_keys(keys))
|
41
|
+
response.headers['Content-Disposition'] = "attachment; filename=#{locale}.yml"
|
42
|
+
render :text => yaml
|
43
|
+
end
|
44
|
+
|
45
|
+
def remove_blanks hash
|
46
|
+
hash.each { |k, v|
|
47
|
+
if !v || v == ''
|
48
|
+
hash.delete k
|
49
|
+
end
|
50
|
+
if v.is_a? Hash
|
51
|
+
remove_blanks v
|
52
|
+
if v == {}
|
53
|
+
hash.delete k
|
54
|
+
end
|
55
|
+
end
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def set_nested(hash, key, value)
|
60
|
+
if key.length == 1
|
61
|
+
hash[key[0]] = value
|
62
|
+
else
|
63
|
+
k = key.shift
|
64
|
+
set_nested(hash[k] ||= {}, key, value)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Stringifying keys for prettier YAML
|
71
|
+
def deep_stringify_keys(hash)
|
72
|
+
hash.inject({}) { |result, (key, value)|
|
73
|
+
value = deep_stringify_keys(value) if value.is_a? Hash
|
74
|
+
result[(key.to_s rescue key) || key] = value
|
75
|
+
result
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def keys_to_yaml(keys)
|
80
|
+
# Using ya2yaml, if available, for UTF8 support
|
81
|
+
if keys.respond_to?(:ya2yaml)
|
82
|
+
keys.ya2yaml(:escape_as_utf8 => true)
|
83
|
+
else
|
84
|
+
keys.to_yaml
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
public
|
89
|
+
|
90
|
+
def update
|
91
|
+
params[:key].each { |k, v|
|
92
|
+
t = Translation.where(:key => k, :locale => @to_locale).first
|
93
|
+
unless t
|
94
|
+
t = Translation.new
|
95
|
+
t.key = k
|
96
|
+
t.locale = @to_locale
|
97
|
+
end
|
98
|
+
next if t.value == v
|
99
|
+
if params[:version][k].to_i == t.updated_at.to_i
|
100
|
+
t.value = v
|
101
|
+
end
|
102
|
+
t.save
|
103
|
+
}
|
104
|
+
if I18n.backend.respond_to? :store_translations
|
105
|
+
I18n.backend.store_translations(@to_locale, RailsI18nterface::Keys.to_deep_hash(params[:key]))
|
106
|
+
end
|
107
|
+
RailsI18nterface::Storage.new(@to_locale).write_to_file
|
108
|
+
RailsI18nterface::Log.new(@from_locale, @to_locale, params[:key].keys).write_to_file
|
109
|
+
force_init_translations # Force reload from YAML file
|
110
|
+
flash[:notice] = "Translations stored"
|
111
|
+
redirect_to root_path(params.slice(:filter, :sort_by, :key_type, :key_pattern, :text_type, :text_pattern))
|
112
|
+
end
|
113
|
+
|
114
|
+
def reload
|
115
|
+
RailsI18nterface::Keys.files = nil
|
116
|
+
redirect_to :action => 'index'
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def initialize_keys
|
122
|
+
@files = RailsI18nterface::Keys.files
|
123
|
+
@keys = (@files.keys.map(&:to_s) + RailsI18nterface::Keys.new.i18n_keys(@from_locale)).uniq
|
124
|
+
@keys.reject! do |key|
|
125
|
+
from_text = lookup(@from_locale, key)
|
126
|
+
# When translating from one language to another, make sure there is a text to translate from.
|
127
|
+
# Always exclude non string translation objects as we don't support editing them in the UI.
|
128
|
+
(@from_locale != @to_locale && !from_text.present?) || (from_text.present? && !from_text.is_a?(String))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def lookup(locale, key)
|
133
|
+
(@dbvalues[locale] && @dbvalues[locale][key]) || I18n.backend.send(:lookup, locale, key)
|
134
|
+
end
|
135
|
+
helper_method :lookup
|
136
|
+
|
137
|
+
def filter_by_translated_or_changed
|
138
|
+
params[:filter] ||= 'all'
|
139
|
+
return if params[:filter] == 'all'
|
140
|
+
@keys.reject! do |key|
|
141
|
+
case params[:filter]
|
142
|
+
when 'untranslated'
|
143
|
+
lookup(@to_locale, key).present?
|
144
|
+
when 'translated'
|
145
|
+
lookup(@to_locale, key).blank?
|
146
|
+
when 'changed'
|
147
|
+
old_from_text(key).blank? || lookup(@from_locale, key) == old_from_text(key)
|
148
|
+
else
|
149
|
+
raise "Unknown filter '#{params[:filter]}'"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def filter_by_key_pattern
|
155
|
+
return if params[:key_pattern].blank?
|
156
|
+
@keys.reject! do |key|
|
157
|
+
case params[:key_type]
|
158
|
+
when "starts_with"
|
159
|
+
if params[:key_pattern] == '.'
|
160
|
+
key.match(/\./)
|
161
|
+
else
|
162
|
+
!key.starts_with?(params[:key_pattern])
|
163
|
+
end
|
164
|
+
when "contains"
|
165
|
+
key.index(params[:key_pattern]).nil?
|
166
|
+
else
|
167
|
+
raise "Unknown key_type '#{params[:key_type]}'"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def filter_by_text_pattern
|
173
|
+
return if params[:text_pattern].blank?
|
174
|
+
@keys.reject! do |key|
|
175
|
+
case params[:text_type]
|
176
|
+
when 'contains'
|
177
|
+
!lookup(@from_locale, key).present? || !lookup(@from_locale, key).to_s.downcase.index(params[:text_pattern].downcase)
|
178
|
+
when 'equals'
|
179
|
+
!lookup(@from_locale, key).present? || lookup(@from_locale, key).to_s.downcase != params[:text_pattern].downcase
|
180
|
+
else
|
181
|
+
raise "Unknown text_type '#{params[:text_type]}'"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def sort_keys
|
187
|
+
params[:sort_by] ||= "key"
|
188
|
+
case params[:sort_by]
|
189
|
+
when "key"
|
190
|
+
@keys.sort!
|
191
|
+
when "text"
|
192
|
+
@keys.sort! do |key1, key2|
|
193
|
+
if lookup(@from_locale, key1).present? && lookup(@from_locale, key2).present?
|
194
|
+
lookup(@from_locale, key1).to_s.downcase <=> lookup(@from_locale, key2).to_s.downcase
|
195
|
+
elsif lookup(@from_locale, key1).present?
|
196
|
+
-1
|
197
|
+
else
|
198
|
+
1
|
199
|
+
end
|
200
|
+
end
|
201
|
+
else
|
202
|
+
raise "Unknown sort_by '#{params[:sort_by]}'"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def paginate_keys
|
207
|
+
params[:page] ||= 1
|
208
|
+
@paginated_keys = @keys[offset, per_page]
|
209
|
+
end
|
210
|
+
|
211
|
+
def offset
|
212
|
+
(params[:page].to_i - 1) * per_page
|
213
|
+
end
|
214
|
+
|
215
|
+
def per_page
|
216
|
+
50
|
217
|
+
end
|
218
|
+
helper_method :per_page
|
219
|
+
|
220
|
+
def init_translations
|
221
|
+
I18n.backend.send(:init_translations) unless I18n.backend.initialized?
|
222
|
+
end
|
223
|
+
|
224
|
+
def force_init_translations
|
225
|
+
I18n.backend.send(:init_translations) rescue false
|
226
|
+
end
|
227
|
+
|
228
|
+
def default_locale
|
229
|
+
I18n.default_locale
|
230
|
+
end
|
231
|
+
|
232
|
+
def set_locale
|
233
|
+
session[:from_locale] ||= default_locale
|
234
|
+
session[:to_locale] ||= :en
|
235
|
+
session[:from_locale] = params[:from_locale] if params[:from_locale].present?
|
236
|
+
session[:to_locale] = params[:to_locale] if params[:to_locale].present?
|
237
|
+
@from_locale = session[:from_locale].to_sym
|
238
|
+
@to_locale = session[:to_locale].to_sym
|
239
|
+
end
|
240
|
+
|
241
|
+
def old_from_text(key)
|
242
|
+
return @old_from_text[key] if @old_from_text && @old_from_text[key]
|
243
|
+
@old_from_text = {}
|
244
|
+
text = key.split(".").inject(log_hash) do |hash, k|
|
245
|
+
hash ? hash[k] : nil
|
246
|
+
end
|
247
|
+
@old_from_text[key] = text
|
248
|
+
end
|
249
|
+
helper_method :old_from_text
|
250
|
+
|
251
|
+
def log_hash
|
252
|
+
@log_hash ||= RailsI18nterface::Log.new(@from_locale, @to_locale, {}).read
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module RailsI18nterface
|
2
|
+
module TranslateHelper
|
3
|
+
|
4
|
+
def simple_filter(labels, param_name = 'filter', selected_value = nil)
|
5
|
+
selected_value ||= params[param_name]
|
6
|
+
filter = []
|
7
|
+
labels.each do |item|
|
8
|
+
if item.is_a?(Array)
|
9
|
+
type, label = item
|
10
|
+
else
|
11
|
+
type = label = item
|
12
|
+
end
|
13
|
+
if type.to_s == selected_value.to_s
|
14
|
+
filter << "<i>#{label}</i>"
|
15
|
+
else
|
16
|
+
link_params = params.merge({param_name.to_s => type})
|
17
|
+
link_params.merge!({"page" => nil}) if param_name.to_s != "page"
|
18
|
+
filter << link_to(label, link_params)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
filter.join(" | ")
|
22
|
+
end
|
23
|
+
|
24
|
+
def n_lines(text, line_size)
|
25
|
+
n_lines = 1
|
26
|
+
if text.present?
|
27
|
+
n_lines = text.split("\n").size
|
28
|
+
if n_lines == 1 && text.length > line_size
|
29
|
+
n_lines = text.length / line_size + 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
n_lines
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_namespace(h)
|
36
|
+
out = '<ul>'
|
37
|
+
dirs = {}
|
38
|
+
root = []
|
39
|
+
h.each do |k,v|
|
40
|
+
if v.is_a? Hash
|
41
|
+
dirs[k] = v
|
42
|
+
else
|
43
|
+
root << k
|
44
|
+
end
|
45
|
+
end
|
46
|
+
out << "<li class=\"dir\"><span class=\"display\" data-id=\".\"></span>ROOT"
|
47
|
+
out << " <span class=\"num\">(#{root.length})</span>"
|
48
|
+
out << '<ul>'
|
49
|
+
root.each do |key|
|
50
|
+
out << "<li class=\"item\" data-id=\"#{key.to_s}\">#{key}</li>"
|
51
|
+
end
|
52
|
+
out << '</ul>'
|
53
|
+
out << '</ul>'
|
54
|
+
out << list_namespace('',dirs)
|
55
|
+
end
|
56
|
+
|
57
|
+
def list_namespace(k,h)
|
58
|
+
out = '<ul>'
|
59
|
+
k != '' && k += '.'
|
60
|
+
h.each do |key,val|
|
61
|
+
if val.is_a? Hash
|
62
|
+
out << "<li class=\"dir\"><span class=\"display\" data-id=\"#{k+key.to_s}\"></span>#{key}"
|
63
|
+
out << " <span class=\"num\">(#{val.length})</span>"
|
64
|
+
out << list_namespace(k+key.to_s,val)
|
65
|
+
else
|
66
|
+
out << "<li class=\"item\" data-id=\"#{k+key.to_s}\">#{key}"
|
67
|
+
end
|
68
|
+
out << '</li>'
|
69
|
+
end
|
70
|
+
out << '</ul>'
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
5
|
+
<title><%= @page_title %></title>
|
6
|
+
<%= stylesheet_link_tag 'rails_i18nterface/application' %>
|
7
|
+
<%= javascript_include_tag 'rails_i18nterface/application' %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<div id="container">
|
11
|
+
<%= yield %>
|
12
|
+
</div>
|
13
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h2>Namespaces</h2>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%
|
2
|
+
n_pages = total_entries/per_page + (total_entries % per_page > 0 ? 1 : 0)
|
3
|
+
current_page = (params[:page] || 1).to_i
|
4
|
+
%>
|
5
|
+
|
6
|
+
<% if n_pages > 1 %>
|
7
|
+
<div class="clearfix">
|
8
|
+
<ul class="paging">
|
9
|
+
<% (1..n_pages).each do |page_number| %>
|
10
|
+
<% if current_page == page_number %>
|
11
|
+
<li class="selected"><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}" ) %></li>
|
12
|
+
<% else %>
|
13
|
+
<li><%= link_to(page_number, params.merge(:page => page_number), :title => "Page #{page_number}") %></li>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
16
|
+
</ul>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
@@ -0,0 +1,132 @@
|
|
1
|
+
<%
|
2
|
+
@page_title = "Translate"
|
3
|
+
show_filters = ["all", "untranslated", "translated"]
|
4
|
+
show_filters << "changed" if @from_locale != @to_locale
|
5
|
+
%>
|
6
|
+
<%= form_tag(params, :method => :get, :name => 'filter_form') do %>
|
7
|
+
<%= hidden_field_tag(:filter, params[:filter]) %>
|
8
|
+
<%= hidden_field_tag(:sort_by, params[:sort_by]) %>
|
9
|
+
<div id="top">
|
10
|
+
<% if @page_title %>
|
11
|
+
<h1>
|
12
|
+
<div class="right">
|
13
|
+
<%= select_tag(:from_locale, options_for_select(I18n.available_locales, @from_locale.to_sym)) %> <span>to</span>
|
14
|
+
<%= select_tag(:to_locale, options_for_select(I18n.available_locales, @to_locale.to_sym)) %>
|
15
|
+
<%= submit_tag "Display" %>
|
16
|
+
</div>
|
17
|
+
<%= link_to '.. /', '../' %>
|
18
|
+
<%= link_to @page_title, root_path %></a>
|
19
|
+
<div class="center">
|
20
|
+
<label>Show:</label> <%= simple_filter(show_filters).html_safe %>
|
21
|
+
Found <strong><%= @total_entries %></strong> messages
|
22
|
+
<%= link_to "Reload messages", translate_reload_path %>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
</h1>
|
26
|
+
<% end %>
|
27
|
+
<% flash.each do |key, msg| %>
|
28
|
+
<div id="<%= key %>"><%= msg %></div>
|
29
|
+
<% end %>
|
30
|
+
</div>
|
31
|
+
<div id="searchbox">
|
32
|
+
|
33
|
+
<%= select_tag(:key_type, options_for_select([["Key contains", 'contains'], ["Key starts with", 'starts_with']], params[:key_type])) %>
|
34
|
+
<%= text_field_tag(:key_pattern, params[:key_pattern], :size => 50, :id => "key_pattern_value", :class => "text-default") %>
|
35
|
+
|
36
|
+
<%= select_tag(:text_type, options_for_select([['Text contains','contains'], ['Text equals','equals']], params[:text_type])) %>
|
37
|
+
<%= text_field_tag(:text_pattern, params[:text_pattern], :size => 50, :id => "text_pattern_value", :class => "text-default") %>
|
38
|
+
|
39
|
+
<%= link_to "clear", params.merge({:text_pattern => nil, :key_pattern => nil}), class: 'btn' %>
|
40
|
+
<%= submit_tag "Search" %>
|
41
|
+
<%= link_to "Export language file", translate_export_path(:locale => @to_locale), class: 'btn sep' %>
|
42
|
+
</div>
|
43
|
+
<% end %>
|
44
|
+
|
45
|
+
<div id="namespaces">
|
46
|
+
<%= build_namespace(@deep_keys).html_safe %>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div id="inside">
|
50
|
+
<div class="paging">
|
51
|
+
<%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
|
52
|
+
</div>
|
53
|
+
|
54
|
+
<% if @total_entries > 0 %>
|
55
|
+
<%= form_tag(translate_path, method: :put) do %>
|
56
|
+
<div>
|
57
|
+
<%= hidden_field_tag(:filter, params[:filter], :id => "hid_filter") %>
|
58
|
+
<%= hidden_field_tag(:sort_by, params[:sort_by], :id => "hid_sort_by") %>
|
59
|
+
<%= hidden_field_tag(:key_type, params[:key_type], :id => "hid_key_type") %>
|
60
|
+
<%= hidden_field_tag(:key_pattern, params[:key_pattern], :id => "hid_key_pattern") %>
|
61
|
+
<%= hidden_field_tag(:text_type, params[:text_type], :id => "hid_text_type") %>
|
62
|
+
<%= hidden_field_tag(:text_pattern, params[:text_pattern], :id => "hid_text_pattern") %>
|
63
|
+
</div>
|
64
|
+
<div class="translations">
|
65
|
+
<p class="translate">
|
66
|
+
Translations from <%= @from_locale %> to <%= @to_locale %>
|
67
|
+
<label>Sort by:</label> <%= simple_filter(["key", "text"], 'sort_by').html_safe %>
|
68
|
+
<%= submit_tag "Save Translations", style: 'float:right;' %>
|
69
|
+
</p>
|
70
|
+
<% @paginated_keys.each do |key|
|
71
|
+
from_text = lookup(@from_locale, key)
|
72
|
+
to_text = lookup(@to_locale, key)
|
73
|
+
line_size = 100
|
74
|
+
n_lines = n_lines(from_text, line_size)
|
75
|
+
field_name = "key[#{key}]"
|
76
|
+
tid = key.split('.').join("_")
|
77
|
+
|
78
|
+
%>
|
79
|
+
<div class="translation">
|
80
|
+
<p class="edit-form">
|
81
|
+
<%= hidden_field_tag("version[#{key}]", @versions[key] || '0') %>
|
82
|
+
<% if n_lines > 1 %>
|
83
|
+
<span class="right">
|
84
|
+
<span class="key"><%=h key %></span>
|
85
|
+
<% if @files[key] %>
|
86
|
+
<span class="file"><%= @files[key].join("</span><span>") %></span>
|
87
|
+
<% end %>
|
88
|
+
</span>
|
89
|
+
</span>
|
90
|
+
<div class="long-translation">
|
91
|
+
<div class="translation-text">
|
92
|
+
<pre id="<%= tid %>_original"><%= from_text %></pre>
|
93
|
+
<div class="clear"></div>
|
94
|
+
</div>
|
95
|
+
<div class="translation-textarea">
|
96
|
+
<%= text_area_tag(field_name, to_text, :rows => n_lines+1, :id => tid) %>
|
97
|
+
<div class="clear"></div>
|
98
|
+
</div>
|
99
|
+
<div class="clear"></div>
|
100
|
+
</div>
|
101
|
+
<% else %>
|
102
|
+
<span class="translation-text">
|
103
|
+
<code class="keytext" id="<%= tid %>_original"><%= from_text %></code>
|
104
|
+
</span>
|
105
|
+
<span class="right">
|
106
|
+
<span class="key" ><%=h key %></span>
|
107
|
+
<% if @files[key] %>
|
108
|
+
<span class="file"><%= @files[key].join("</span><span>") %></span>
|
109
|
+
<% end %>
|
110
|
+
</span>
|
111
|
+
</span>
|
112
|
+
|
113
|
+
<%= text_field_tag(field_name, to_text, :size => line_size, :id => tid) %>
|
114
|
+
<% end %>
|
115
|
+
</p>
|
116
|
+
<p>
|
117
|
+
</p>
|
118
|
+
</div>
|
119
|
+
<% end %>
|
120
|
+
<p class="translate">
|
121
|
+
Translations from <%= @from_locale %> to <%= @to_locale %>
|
122
|
+
<%= submit_tag "Save Translations", style: 'float:right' %>
|
123
|
+
</p>
|
124
|
+
</div>
|
125
|
+
<% end %>
|
126
|
+
<% end %>
|
127
|
+
|
128
|
+
<div class="paging clear">
|
129
|
+
<%= render :partial => 'pagination', :locals => {:total_entries => @total_entries, :per_page => per_page} %>
|
130
|
+
</div>
|
131
|
+
|
132
|
+
</div>
|