interpret 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/.gitignore +11 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +2 -0
  4. data/app/controllers/interpret/base_controller.rb +10 -0
  5. data/app/controllers/interpret/search_controller.rb +7 -0
  6. data/app/controllers/interpret/tools_controller.rb +39 -0
  7. data/app/controllers/interpret/translations_controller.rb +47 -0
  8. data/app/models/interpret/translation.rb +257 -0
  9. data/app/sweepers/interpret/base_sweeper.rb +14 -0
  10. data/app/sweepers/interpret/translation_sweeper.rb +14 -0
  11. data/app/views/interpret/search/index.html.erb +29 -0
  12. data/app/views/interpret/search/perform.html.erb +38 -0
  13. data/app/views/interpret/tools/index.html.erb +38 -0
  14. data/app/views/interpret/translations/_form.html.erb +5 -0
  15. data/app/views/interpret/translations/_listing.html.erb +22 -0
  16. data/app/views/interpret/translations/edit.html.erb +5 -0
  17. data/app/views/interpret/translations/index.html.erb +28 -0
  18. data/app/views/layouts/interpret.html.erb +41 -0
  19. data/config/routes.rb +20 -0
  20. data/interpret.gemspec +30 -0
  21. data/lib/generators/interpret/migration_generator.rb +25 -0
  22. data/lib/generators/interpret/setup_generator.rb +21 -0
  23. data/lib/generators/interpret/templates/migration.rb +16 -0
  24. data/lib/generators/interpret/views_generator.rb +16 -0
  25. data/lib/interpret/capistrano.rb +15 -0
  26. data/lib/interpret/engine.rb +23 -0
  27. data/lib/interpret/helpers.rb +45 -0
  28. data/lib/interpret/lazy_hash.rb +21 -0
  29. data/lib/interpret/logger.rb +7 -0
  30. data/lib/interpret/version.rb +3 -0
  31. data/lib/interpret.rb +30 -0
  32. data/lib/tasks/interpret.rake +11 -0
  33. data/public/javascripts/jquery.purr.js +180 -0
  34. data/public/stylesheets/folder.png +0 -0
  35. data/public/stylesheets/interpret_style.css +542 -0
  36. data/test_app/Gemfile +11 -0
  37. data/test_app/README +256 -0
  38. data/test_app/Rakefile +7 -0
  39. data/test_app/app/controllers/application_controller.rb +3 -0
  40. data/test_app/app/controllers/pages_controller.rb +3 -0
  41. data/test_app/app/helpers/application_helper.rb +2 -0
  42. data/test_app/app/sweepers/page_sweeper.rb +12 -0
  43. data/test_app/app/views/layouts/application.html.erb +15 -0
  44. data/test_app/app/views/pages/contact.html.haml +8 -0
  45. data/test_app/app/views/pages/index.html.haml +9 -0
  46. data/test_app/config/application.rb +42 -0
  47. data/test_app/config/boot.rb +13 -0
  48. data/test_app/config/database.yml +23 -0
  49. data/test_app/config/environment.rb +5 -0
  50. data/test_app/config/environments/development.rb +27 -0
  51. data/test_app/config/environments/production.rb +51 -0
  52. data/test_app/config/environments/test.rb +35 -0
  53. data/test_app/config/initializers/backtrace_silencers.rb +7 -0
  54. data/test_app/config/initializers/inflections.rb +10 -0
  55. data/test_app/config/initializers/interpret.rb +2 -0
  56. data/test_app/config/initializers/mime_types.rb +5 -0
  57. data/test_app/config/initializers/secret_token.rb +7 -0
  58. data/test_app/config/initializers/session_store.rb +8 -0
  59. data/test_app/config/locales/ca.yml +6 -0
  60. data/test_app/config/locales/es.yml +48 -0
  61. data/test_app/config/routes.rb +4 -0
  62. data/test_app/config.ru +4 -0
  63. data/test_app/db/migrate/20110209185258_interpret_create_translations.rb +16 -0
  64. data/test_app/db/schema.rb +23 -0
  65. data/test_app/db/seeds.rb +0 -0
  66. data/test_app/lib/lazy_hash.rb +22 -0
  67. data/test_app/lib/tasks/.gitkeep +0 -0
  68. data/test_app/lib/tasks/setup.rake +19 -0
  69. data/test_app/public/404.html +26 -0
  70. data/test_app/public/422.html +26 -0
  71. data/test_app/public/500.html +26 -0
  72. data/test_app/public/favicon.ico +0 -0
  73. data/test_app/public/index.html +29 -0
  74. data/test_app/public/javascripts/application.js +2 -0
  75. data/test_app/public/javascripts/best_in_place.js +456 -0
  76. data/test_app/public/javascripts/controls.js +965 -0
  77. data/test_app/public/javascripts/dragdrop.js +974 -0
  78. data/test_app/public/javascripts/effects.js +1123 -0
  79. data/test_app/public/javascripts/jquery.purr.js +180 -0
  80. data/test_app/public/javascripts/prototype.js +6001 -0
  81. data/test_app/public/javascripts/rails.js +134 -0
  82. data/test_app/public/robots.txt +5 -0
  83. data/test_app/public/stylesheets/.gitkeep +0 -0
  84. data/test_app/public/stylesheets/folder.png +0 -0
  85. data/test_app/public/stylesheets/interpret_style.css +530 -0
  86. data/test_app/script/rails +6 -0
  87. data/test_app/vendor/plugins/.gitkeep +0 -0
  88. metadata +262 -0
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+
5
+ Gemfile.lock
6
+ .DS_Store
7
+ test_app/.bundle
8
+ test_app/db/*.sqlite3
9
+ test_app/log/*.log
10
+ test_app/tmp/**/*
11
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in interpret.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,10 @@
1
+ class Interpret::BaseController < eval(Interpret.controller.classify)
2
+ before_filter :set_locale
3
+ layout 'interpret'
4
+
5
+ private
6
+ def set_locale
7
+ I18n.locale = params[:locale] if params[:locale]
8
+ end
9
+ end
10
+
@@ -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,5 @@
1
+ <%= form_for @translation, :url => translation_path(@translation) do |f| %>
2
+ <%= f.label :value %>
3
+ <%= f.text_field :value, :value => @translation.value %>
4
+ <%= f.submit %>
5
+ <% 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,5 @@
1
+ <h1>[<%= I18n.locale %>] Editing '<%= @translation.key %>'</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to "Back", translations_path %>
@@ -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