interpret 0.1.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.
- 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
|