interpret 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/app/controllers/interpret/base_controller.rb +10 -0
- data/app/controllers/interpret/search_controller.rb +7 -0
- data/app/controllers/interpret/tools_controller.rb +39 -0
- data/app/controllers/interpret/translations_controller.rb +47 -0
- data/app/models/interpret/translation.rb +257 -0
- data/app/sweepers/interpret/base_sweeper.rb +14 -0
- data/app/sweepers/interpret/translation_sweeper.rb +14 -0
- data/app/views/interpret/search/index.html.erb +29 -0
- data/app/views/interpret/search/perform.html.erb +38 -0
- data/app/views/interpret/tools/index.html.erb +38 -0
- data/app/views/interpret/translations/_form.html.erb +5 -0
- data/app/views/interpret/translations/_listing.html.erb +22 -0
- data/app/views/interpret/translations/edit.html.erb +5 -0
- data/app/views/interpret/translations/index.html.erb +28 -0
- data/app/views/layouts/interpret.html.erb +41 -0
- data/config/routes.rb +20 -0
- data/interpret.gemspec +30 -0
- data/lib/generators/interpret/migration_generator.rb +25 -0
- data/lib/generators/interpret/setup_generator.rb +21 -0
- data/lib/generators/interpret/templates/migration.rb +16 -0
- data/lib/generators/interpret/views_generator.rb +16 -0
- data/lib/interpret/capistrano.rb +15 -0
- data/lib/interpret/engine.rb +23 -0
- data/lib/interpret/helpers.rb +45 -0
- data/lib/interpret/lazy_hash.rb +21 -0
- data/lib/interpret/logger.rb +7 -0
- data/lib/interpret/version.rb +3 -0
- data/lib/interpret.rb +30 -0
- data/lib/tasks/interpret.rake +11 -0
- data/public/javascripts/jquery.purr.js +180 -0
- data/public/stylesheets/folder.png +0 -0
- data/public/stylesheets/interpret_style.css +542 -0
- data/test_app/Gemfile +11 -0
- data/test_app/README +256 -0
- data/test_app/Rakefile +7 -0
- data/test_app/app/controllers/application_controller.rb +3 -0
- data/test_app/app/controllers/pages_controller.rb +3 -0
- data/test_app/app/helpers/application_helper.rb +2 -0
- data/test_app/app/sweepers/page_sweeper.rb +12 -0
- data/test_app/app/views/layouts/application.html.erb +15 -0
- data/test_app/app/views/pages/contact.html.haml +8 -0
- data/test_app/app/views/pages/index.html.haml +9 -0
- data/test_app/config/application.rb +42 -0
- data/test_app/config/boot.rb +13 -0
- data/test_app/config/database.yml +23 -0
- data/test_app/config/environment.rb +5 -0
- data/test_app/config/environments/development.rb +27 -0
- data/test_app/config/environments/production.rb +51 -0
- data/test_app/config/environments/test.rb +35 -0
- data/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test_app/config/initializers/inflections.rb +10 -0
- data/test_app/config/initializers/interpret.rb +2 -0
- data/test_app/config/initializers/mime_types.rb +5 -0
- data/test_app/config/initializers/secret_token.rb +7 -0
- data/test_app/config/initializers/session_store.rb +8 -0
- data/test_app/config/locales/ca.yml +6 -0
- data/test_app/config/locales/es.yml +48 -0
- data/test_app/config/routes.rb +4 -0
- data/test_app/config.ru +4 -0
- data/test_app/db/migrate/20110209185258_interpret_create_translations.rb +16 -0
- data/test_app/db/schema.rb +23 -0
- data/test_app/db/seeds.rb +0 -0
- data/test_app/lib/lazy_hash.rb +22 -0
- data/test_app/lib/tasks/.gitkeep +0 -0
- data/test_app/lib/tasks/setup.rake +19 -0
- data/test_app/public/404.html +26 -0
- data/test_app/public/422.html +26 -0
- data/test_app/public/500.html +26 -0
- data/test_app/public/favicon.ico +0 -0
- data/test_app/public/index.html +29 -0
- data/test_app/public/javascripts/application.js +2 -0
- data/test_app/public/javascripts/best_in_place.js +456 -0
- data/test_app/public/javascripts/controls.js +965 -0
- data/test_app/public/javascripts/dragdrop.js +974 -0
- data/test_app/public/javascripts/effects.js +1123 -0
- data/test_app/public/javascripts/jquery.purr.js +180 -0
- data/test_app/public/javascripts/prototype.js +6001 -0
- data/test_app/public/javascripts/rails.js +134 -0
- data/test_app/public/robots.txt +5 -0
- data/test_app/public/stylesheets/.gitkeep +0 -0
- data/test_app/public/stylesheets/folder.png +0 -0
- data/test_app/public/stylesheets/interpret_style.css +530 -0
- data/test_app/script/rails +6 -0
- data/test_app/vendor/plugins/.gitkeep +0 -0
- metadata +262 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
class Interpret::SearchController < Interpret::BaseController
|
2
|
+
|
3
|
+
def perform
|
4
|
+
t = Interpret::Translation.arel_table
|
5
|
+
@translations = Interpret::Translation.locale(I18n.locale).where(t[:key].matches("%#{params[:key]}%").and(t[:value].matches("%#{params[:value]}%")) )
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Interpret::ToolsController < Interpret::BaseController
|
2
|
+
|
3
|
+
def dump
|
4
|
+
Interpret::Translation.dump
|
5
|
+
|
6
|
+
session.delete(:tree)
|
7
|
+
Interpret.backend.reload! if Interpret.backend
|
8
|
+
redirect_to interpret_tools_url, :notice => "Dump done."
|
9
|
+
end
|
10
|
+
|
11
|
+
def export
|
12
|
+
require 'ya2yaml'
|
13
|
+
|
14
|
+
translations = Interpret::Translation.locale(I18n.locale).all
|
15
|
+
hash = Interpret::Translation.export(translations)
|
16
|
+
text = hash.ya2yaml
|
17
|
+
|
18
|
+
send_data text[5..text.length], :filename => "#{I18n.locale}.yml"
|
19
|
+
end
|
20
|
+
|
21
|
+
def import
|
22
|
+
unless params.has_key? :file
|
23
|
+
redirect_to interpret_tools_url, :alert => "You have to select a file to import."
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
Interpret::Translation.import(params[:file])
|
29
|
+
rescue Exception => e
|
30
|
+
redirect_to interpret_tools_url, :alert => e
|
31
|
+
end
|
32
|
+
|
33
|
+
session.delete(:tree)
|
34
|
+
Interpret.backend.reload! if Interpret.backend
|
35
|
+
|
36
|
+
redirect_to interpret_tools_url, :notice => "Import successfully done."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class Interpret::TranslationsController < Interpret::BaseController
|
2
|
+
cache_sweeper eval(Interpret.sweeper.to_s.classify) if Interpret.sweeper
|
3
|
+
cache_sweeper Interpret::TranslationSweeper
|
4
|
+
before_filter :get_tree, :only => :index
|
5
|
+
|
6
|
+
def index
|
7
|
+
key = params[:key]
|
8
|
+
t = Interpret::Translation.arel_table
|
9
|
+
if key
|
10
|
+
@translations = Interpret::Translation.locale(I18n.locale).where(t[:key].matches("#{key}.%"))
|
11
|
+
@translations = @translations.select{|x| x.key =~ /#{key}\.\w+$/}
|
12
|
+
else
|
13
|
+
@translations = Interpret::Translation.locale(I18n.locale).where(t[:key].does_not_match("%.%")).paginate :page => params[:page]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def edit
|
18
|
+
@translation = Interpret::Translation.find(params[:id])
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
@translation = Interpret::Translation.find(params[:id])
|
23
|
+
old_value = @translation.value
|
24
|
+
|
25
|
+
respond_to do |format|
|
26
|
+
if @translation.update_attributes(params[:interpret_translation])
|
27
|
+
msg = respond_to?(:current_user) ? "By [#{current_user}]. " : ""
|
28
|
+
msg << "Locale: [#{@translation.locale}], key: [#{@translation.key}]. The translation has been changed from [#{old_value}] to [#{@translation.value}]"
|
29
|
+
Interpret.logger.info msg
|
30
|
+
|
31
|
+
format.html { redirect_to(translations_url)}
|
32
|
+
format.xml { head :ok }
|
33
|
+
format.json { head :ok }
|
34
|
+
else
|
35
|
+
format.html { render :action => "edit" }
|
36
|
+
format.xml { render :xml => @translation.errors, :status => :unprocessable_entity }
|
37
|
+
format.json { render :status => :unprocessable_entity }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def get_tree
|
44
|
+
@tree = session[:tree] ||= Interpret::Translation.get_tree
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,257 @@
|
|
1
|
+
require 'i18n/backend/active_record/translation'
|
2
|
+
|
3
|
+
|
4
|
+
module Interpret
|
5
|
+
|
6
|
+
class TableDoesNotExists < ActiveRecord::ActiveRecordError; end
|
7
|
+
|
8
|
+
unless I18n::Backend::ActiveRecord::Translation.table_exists?
|
9
|
+
raise TableDoesNotExists, "You must setup a translations table first"
|
10
|
+
end
|
11
|
+
|
12
|
+
class Translation < I18n::Backend::ActiveRecord::Translation
|
13
|
+
default_scope order('locale ASC')
|
14
|
+
|
15
|
+
class << self
|
16
|
+
# Generates a hash representing the tree structure of the translations
|
17
|
+
# for the given locale. It includes only "folders" in the sense of
|
18
|
+
# locale keys that includes some real translations, or other keys.
|
19
|
+
def get_tree(lang = I18n.locale)
|
20
|
+
t = arel_table
|
21
|
+
all_trans = locale(lang).select(t[:key]).where(t[:key].matches("%.%")).all
|
22
|
+
|
23
|
+
tree = LazyHash.build_hash
|
24
|
+
all_trans = all_trans.map{|x| x.key.split(".")[0..-2].join(".")}.uniq
|
25
|
+
all_trans.each do |x|
|
26
|
+
LazyHash.lazy_add(tree, x, {})
|
27
|
+
end
|
28
|
+
|
29
|
+
# Generate a new clean hash without the proc's from LazyHash.
|
30
|
+
# Includes a root level for convenience, to be exactly like the
|
31
|
+
# structure of a .yml file which has the "en" root key for example.
|
32
|
+
{"index" => eval(tree.inspect)}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generate a hash from the given translations. That hash can be
|
36
|
+
# ya2yaml'ized to get a standard .yml locale file.
|
37
|
+
def export(translations)
|
38
|
+
res = LazyHash.build_hash
|
39
|
+
|
40
|
+
translations.each do |e|
|
41
|
+
LazyHash.lazy_add(res, "#{e.locale}.#{e.key}", e.value)
|
42
|
+
end
|
43
|
+
res
|
44
|
+
end
|
45
|
+
|
46
|
+
# Import the contents of the given .yml locale file into the database
|
47
|
+
# backend. All the existing translations for the given language will be
|
48
|
+
# erased, the backend will contain only the translations from the file
|
49
|
+
# (in that language).
|
50
|
+
#
|
51
|
+
# The language will be obtained from the first unique key of the yml
|
52
|
+
# file.
|
53
|
+
def import(file)
|
54
|
+
if file.content_type && file.content_type.match(/^text\/.*/).nil?
|
55
|
+
raise ArgumentError, "Invalid file content type"
|
56
|
+
end
|
57
|
+
hash = YAML.load file
|
58
|
+
raise ArgumentError, "the YAML file must contain an unique first key representing the locale" unless hash.keys.count == 1
|
59
|
+
|
60
|
+
lang = hash.keys.first
|
61
|
+
to_remove = locale(lang).all
|
62
|
+
to_remove.each do |x|
|
63
|
+
x.destroy
|
64
|
+
end
|
65
|
+
records = parse_hash(hash.first[1], lang)
|
66
|
+
# TODO: Replace with activerecord-import bulk inserts
|
67
|
+
transaction do
|
68
|
+
records.each {|x| x.save!}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Dump all contents from *.yml locale files into the database.
|
73
|
+
# CAUTION: All existing data will be erased!
|
74
|
+
#
|
75
|
+
# It will create a "#{locale}.yml.backup" file into config/locales
|
76
|
+
# for each language present in the database, in case you want to
|
77
|
+
# recover some of your just-erased translations.
|
78
|
+
# If you don't want backups, set:
|
79
|
+
#
|
80
|
+
# Interpret.options[:dump_without_backup] = true
|
81
|
+
def dump
|
82
|
+
files = Dir[Rails.root.join("config", "locales", "*.yml").to_s]
|
83
|
+
delete_all
|
84
|
+
|
85
|
+
records = []
|
86
|
+
files.each do |f|
|
87
|
+
ar = YAML.load_file f
|
88
|
+
locale = ar.keys.first
|
89
|
+
records += parse_hash(ar.first[1], locale)
|
90
|
+
end
|
91
|
+
|
92
|
+
# TODO: Replace with activerecord-import bulk inserts
|
93
|
+
transaction do
|
94
|
+
records.each {|x| x.save!}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Run a smart update from the translations in .yml files into the
|
99
|
+
# databse backend. It issues a merging from both, comparing each key
|
100
|
+
# present in the db with the one from the yml file.
|
101
|
+
#
|
102
|
+
# The use case beyond this arquitecture presuposes some things:
|
103
|
+
#
|
104
|
+
# 1) You're working in development mode with the default I18n backend,
|
105
|
+
# that is with the translations in the config/locales/*.yml files.
|
106
|
+
#
|
107
|
+
# 2) Your application is deployed in production and running well. Also,
|
108
|
+
# it has support to modify it's contents (from this very gem of course)
|
109
|
+
# on live, so its possible that your customer has changed a sentence or
|
110
|
+
# a title of the site. And you want to preserve that.
|
111
|
+
#
|
112
|
+
# 3) In general, from the very moment you choose to give the users (or
|
113
|
+
# admins) of your site the ability to change the contents, that contents
|
114
|
+
# are no longer part of the "project" (are checked in in git, to be
|
115
|
+
# specific), they are now part of the dynamic contents of the site just
|
116
|
+
# as if they were models in your db.
|
117
|
+
#
|
118
|
+
# In development, you define a "content layout" in the sense of a
|
119
|
+
# specific locale keys hierarchy. How many paragraphs are in your views,
|
120
|
+
# how many titles, etc... But the real paragraphs are in the production
|
121
|
+
# database.
|
122
|
+
#
|
123
|
+
# So, with this "update" action, you are updating that "contents layout"
|
124
|
+
# with the new one you just designed in development.
|
125
|
+
#
|
126
|
+
# Also keep in mind that rails let you have a diferent locale key
|
127
|
+
# hierarchy for each language, and this behaviour is prohibited in
|
128
|
+
# interpret.
|
129
|
+
# Here, the I18n.default_locale configured in your app is considered the
|
130
|
+
# main one, that is, the only language that can be trusted to have all
|
131
|
+
# the required and correct locale keys.
|
132
|
+
# This will be used to check for inconsitent translations into other
|
133
|
+
# languages, knowing what you haven't translated yet.
|
134
|
+
#
|
135
|
+
# What does all that means?
|
136
|
+
#
|
137
|
+
# - First of all, get the locale keys for the main language from yml files.
|
138
|
+
# - For all of these locale keys, do:
|
139
|
+
# - If a key is present in the db, but not in the new ones, remove
|
140
|
+
# it. You have removed it from the new content layout, so it's no longer
|
141
|
+
# needed.
|
142
|
+
# - If the key is not present in the db, it's new. So, create a new
|
143
|
+
# entry for that key in each language. Look if a translation for that
|
144
|
+
# key exists in yml files for each language, if it exists, use it. If
|
145
|
+
# not, left it empty.
|
146
|
+
# - If the key already exists in the db, do nothing. Maybe somone has
|
147
|
+
# changed that content in production, and you don't want to lose
|
148
|
+
# that. Or maybe you do want to change that content, because you
|
149
|
+
# just added the correct sentence in the yml files. It's up to you to
|
150
|
+
# do the right thing.
|
151
|
+
def update
|
152
|
+
files = Dir[Rails.root.join("config", "locales", "*.yml").to_s]
|
153
|
+
|
154
|
+
@languages = {}
|
155
|
+
@main = {}
|
156
|
+
files.each do |f|
|
157
|
+
ar = YAML.load_file f
|
158
|
+
lang = ar.keys.first
|
159
|
+
@languages[lang.to_s] = ar.first[1]
|
160
|
+
if I18n.default_locale.to_s == lang.to_s
|
161
|
+
@main = ar.first[1]
|
162
|
+
@main_lang = lang
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
sync(@main)
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
def sync(hash, prefix = "", existing = nil)
|
171
|
+
if existing.nil?
|
172
|
+
translations = locale(@main_lang).all
|
173
|
+
existing = export(translations)
|
174
|
+
existing = existing.first[1] unless existing.empty?
|
175
|
+
end
|
176
|
+
|
177
|
+
hash.keys.each do |x|
|
178
|
+
existing.delete(x)
|
179
|
+
|
180
|
+
if hash[x].kind_of?(Hash)
|
181
|
+
sync(hash[x], "#{prefix}#{x}.", existing[x])
|
182
|
+
else
|
183
|
+
old = locale(@main_lang).find_by_key("#{prefix}#{x}")
|
184
|
+
|
185
|
+
unless old
|
186
|
+
# Creates the new entry
|
187
|
+
create_new_translation("#{prefix}#{x}")
|
188
|
+
else
|
189
|
+
# Check if the entry exists in the other languages
|
190
|
+
check_in_other_langs("#{prefix}#{x}")
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
if prefix.blank?
|
196
|
+
remove_unused_keys(existing)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# Check if the the given key exists in all languages except @main. If
|
201
|
+
# not, create an entry.
|
202
|
+
def check_in_other_langs(key)
|
203
|
+
(@languages.keys - [@main_lang]).each do |lang|
|
204
|
+
trans = locale(lang).find_by_key(key)
|
205
|
+
if trans.nil?
|
206
|
+
create! :locale => lang,
|
207
|
+
:key => key,
|
208
|
+
:value => ""
|
209
|
+
Interpret.logger.info "Created inexistent key [#{key}] for lang [#{lang}]"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def create_new_translation(key)
|
215
|
+
@languages.keys.each do |lang|
|
216
|
+
origin_hash = @languages[lang].clone
|
217
|
+
key.split(".")[0..-2].each do |key|
|
218
|
+
origin_hash = origin_hash[key]
|
219
|
+
end
|
220
|
+
value = origin_hash[key.split(".").last]
|
221
|
+
create! :locale => lang,
|
222
|
+
:key => key,
|
223
|
+
:value => value
|
224
|
+
end
|
225
|
+
Interpret.logger.info "New key created [#{key}] for languages #{@languages.keys.inspect}"
|
226
|
+
end
|
227
|
+
|
228
|
+
def remove_unused_keys(hash, prefix = "")
|
229
|
+
hash.keys.each do |x|
|
230
|
+
if hash[x].kind_of?(Hash)
|
231
|
+
remove_unused_keys(hash[x], "#{prefix}#{x}.")
|
232
|
+
else
|
233
|
+
delete_all(:locale => @languages.keys, :key => "#{prefix}#{x}")
|
234
|
+
Interpret.logger.info "Removing unused key #{prefix}#{x}"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def parse_hash(dict, locale, prefix = "")
|
240
|
+
res = []
|
241
|
+
dict.keys.each do |x|
|
242
|
+
if dict[x].kind_of?(Hash)
|
243
|
+
res += parse_hash(dict[x], locale, "#{prefix}#{x}.")
|
244
|
+
else
|
245
|
+
res << new(:locale => locale,
|
246
|
+
:key => "#{prefix}#{x}",
|
247
|
+
:value => dict[x])
|
248
|
+
end
|
249
|
+
end
|
250
|
+
res
|
251
|
+
end
|
252
|
+
|
253
|
+
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Interpret::BaseSweeper < ActionController::Caching::Sweeper
|
2
|
+
observe Interpret::Translation
|
3
|
+
|
4
|
+
def after_update(translation)
|
5
|
+
expire_cache(translation)
|
6
|
+
end
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
# Implement user's custom expire logic
|
11
|
+
def expire_cache(translation)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Interpret::TranslationSweeper < ActionController::Caching::Sweeper
|
2
|
+
observe Interpret::Translation
|
3
|
+
|
4
|
+
def after_update(translation)
|
5
|
+
Interpret.backend.reload! if Interpret.backend
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
def expire_cache
|
10
|
+
#expire_action :controller => "interpret/translations", :action => :tree
|
11
|
+
session.delete(:tree)
|
12
|
+
Interpret.backend.reload! if Interpret.backend
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<div id="header">
|
2
|
+
<h1>Search translations</h1>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<div id="search">
|
6
|
+
<p>Enter a search term for the key and/or the value of the translation</p>
|
7
|
+
|
8
|
+
<%= form_tag interpret_search_for_path do %>
|
9
|
+
<%= label_tag "key", "Key value" %>
|
10
|
+
<br />
|
11
|
+
<%= text_field_tag "key" %>
|
12
|
+
<br />
|
13
|
+
|
14
|
+
<%= label_tag "value", "Translation text" %>
|
15
|
+
<br />
|
16
|
+
<%= text_field_tag "value" %>
|
17
|
+
<br />
|
18
|
+
|
19
|
+
<%= submit_tag "SEARCH" %>
|
20
|
+
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<%= content_for :sidebar do %>
|
24
|
+
<h2>Search</h2>
|
25
|
+
<p>
|
26
|
+
You can use this search feature to look into all the translations. Can be filtered by language, key and phrase.
|
27
|
+
</p>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<%= content_for :title do %>
|
2
|
+
Search translations
|
3
|
+
<%= "by " unless params[:key].blank? && params[:value].blank? %>
|
4
|
+
<%= params[:key] unless params[:key].blank? %>
|
5
|
+
<%= "and " unless params[:key].blank? || params[:value].blank? %>
|
6
|
+
<%= params[:value] unless params[:value].blank? %>
|
7
|
+
<% end %>
|
8
|
+
|
9
|
+
<div id="header">
|
10
|
+
<h1>Search translations</h1>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
|
14
|
+
<%= render 'interpret/translations/listing' %>
|
15
|
+
|
16
|
+
|
17
|
+
<%= content_for :sidebar do %>
|
18
|
+
<h2>Search</h2>
|
19
|
+
<p>
|
20
|
+
<%= @translations.size %> results found.
|
21
|
+
</p>
|
22
|
+
<div id="side_search">
|
23
|
+
<%= form_tag interpret_search_for_path do %>
|
24
|
+
<%= label_tag "key", "Key value" %>
|
25
|
+
<br />
|
26
|
+
<%= text_field_tag "key", params[:key] %>
|
27
|
+
<br />
|
28
|
+
|
29
|
+
<%= label_tag "value", "Translation text" %>
|
30
|
+
<br />
|
31
|
+
<%= text_field_tag "value", params[:value] %>
|
32
|
+
<br />
|
33
|
+
|
34
|
+
<%= submit_tag "SEARCH" %>
|
35
|
+
|
36
|
+
<% end %>
|
37
|
+
</div>
|
38
|
+
<% end %>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<div class="header">
|
2
|
+
<h1>Your master language</h1>
|
3
|
+
</div>
|
4
|
+
<p>
|
5
|
+
Currently your primary language is <b><%= I18n.default_locale %></b>. This
|
6
|
+
language will be used as a reference for all your translation work, you
|
7
|
+
can change it below:
|
8
|
+
</p>
|
9
|
+
<p><em>TODO</em></p>
|
10
|
+
|
11
|
+
<div class="header">
|
12
|
+
<h1>Dump .yml contents into database</h1>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<p>With this option you can export all of your *.yml contents into the database backend<br/>
|
16
|
+
<b>Be aware!!</b> All of your current database translations will be erased
|
17
|
+
</p>
|
18
|
+
|
19
|
+
<% if Rails.env == "production" %>
|
20
|
+
<p><b>MY GOD!!! You're in PRODUCTION!! You're sure you wanna do this??</b></p>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<p>
|
24
|
+
<%= button_to "Run the migration", dump_interpret_tools_path %>
|
25
|
+
</p>
|
26
|
+
|
27
|
+
<div class="header">
|
28
|
+
<h1>Tools for import/export locale data</h1>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<p><%= link_to "Download", export_interpret_tools_path %> the current translations for '<%= I18n.locale %>' language as .yml file</p>
|
32
|
+
<p>Upload your .yml file for '<%= I18n.locale %>' language</p>
|
33
|
+
<p>
|
34
|
+
<%= form_tag import_interpret_tools_path, :multipart => true do %>
|
35
|
+
<%= label_tag "File:" %>
|
36
|
+
<%= file_field_tag :file %>
|
37
|
+
<%= submit_tag "Upload" %>
|
38
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<table>
|
2
|
+
<thead>
|
3
|
+
<tr class="header">
|
4
|
+
<th>Key</th>
|
5
|
+
<th>Content</th>
|
6
|
+
</tr>
|
7
|
+
</thead>
|
8
|
+
<tbody>
|
9
|
+
<% @translations.each do |x| %>
|
10
|
+
<tr id="translation_<%= x.id %>">
|
11
|
+
<td><%= x.key %></td>
|
12
|
+
<td>
|
13
|
+
<%= best_in_place x, :value,
|
14
|
+
:type => :textarea,
|
15
|
+
:path => interpret_translation_path(x),
|
16
|
+
:activator => "#translation_#{x.id}",
|
17
|
+
:sanitize => false %>
|
18
|
+
</td>
|
19
|
+
</tr>
|
20
|
+
<% end %>
|
21
|
+
</tbody>
|
22
|
+
</table>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<%= content_for :title do %>
|
2
|
+
Translation list
|
3
|
+
<% end %>
|
4
|
+
<div id="header">
|
5
|
+
<h1>Translations for <%= I18n.locale %></h1>
|
6
|
+
</div>
|
7
|
+
<p>
|
8
|
+
Below are the translations without any particulary key in your application.
|
9
|
+
That use to be some global names or terms for common use along all the site,
|
10
|
+
which doesn't belong to any page or section in particulary. To dive into the
|
11
|
+
rest of your app's contents, navigate using the tree in the left, that shows your
|
12
|
+
locales structure.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<%= render 'interpret/translations/listing' %>
|
16
|
+
|
17
|
+
<%= content_for :sidebar do %>
|
18
|
+
<div id="tree_sidebar">
|
19
|
+
<h3>
|
20
|
+
<% if params[:key] %>
|
21
|
+
/<%= params[:key].split(".").join("/") %>
|
22
|
+
<% else %>
|
23
|
+
/
|
24
|
+
<% end %>
|
25
|
+
</h3>
|
26
|
+
<%= show_interpret_tree(@tree, params[:key]) %>
|
27
|
+
</div>
|
28
|
+
<% end %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>INTERPRET - <%= yield :title %></title>
|
5
|
+
<%= stylesheet_link_tag "interpret_style" %>
|
6
|
+
<%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" %>
|
7
|
+
<%= javascript_include_tag "jquery.purr" %>
|
8
|
+
<%= javascript_include_tag "best_in_place" %>
|
9
|
+
<%= csrf_meta_tag %>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div id="container">
|
13
|
+
<div class="menu grid_16">
|
14
|
+
<%= interpret_section_link_to "Overview", interpret_root_path %> |
|
15
|
+
<%= interpret_section_link_to "Tools", interpret_tools_path %> |
|
16
|
+
<%= interpret_section_link_to "Search", interpret_search_path %>
|
17
|
+
<hr />
|
18
|
+
</div>
|
19
|
+
<div class="menu grid_16">
|
20
|
+
Languages:
|
21
|
+
<% I18n.available_locales.each do |locale| %>
|
22
|
+
<%= link_to locale, :locale => locale %>
|
23
|
+
<% end %>
|
24
|
+
<hr />
|
25
|
+
</div>
|
26
|
+
<div id="sidebar" class="grid_3">
|
27
|
+
<%= yield :sidebar %>
|
28
|
+
</div>
|
29
|
+
<div id="main" class="grid_13">
|
30
|
+
<%= yield %>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<%= javascript_tag do %>
|
35
|
+
$(document).ready(function() {
|
36
|
+
/* Activating Best In Place */
|
37
|
+
jQuery(".best_in_place").best_in_place()
|
38
|
+
});
|
39
|
+
<% end %>
|
40
|
+
</body>
|
41
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
scope Interpret.scope do
|
3
|
+
namespace :interpret do
|
4
|
+
resources :translations, :only => [:edit, :update]
|
5
|
+
|
6
|
+
resources :tools, :only => :index do
|
7
|
+
collection do
|
8
|
+
get :export
|
9
|
+
post :import
|
10
|
+
post :dump
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
match "search", :to => "search#index"
|
15
|
+
match "search_for", :to => "search#perform"
|
16
|
+
|
17
|
+
root :to => "translations#index"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|