tr8n 3.1.5 → 3.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -1
- data/.rvmrc +1 -1
- data/Gemfile.lock +5 -5
- data/README.rdoc +36 -17
- data/app/assets/javascripts/tr8n/tr8n.js +31 -19
- data/app/controllers/tr8n/help_controller.rb +12 -2
- data/app/models/tr8n/language.rb +7 -3
- data/app/models/tr8n/translation.rb +11 -8
- data/app/models/tr8n/translation_domain.rb +1 -1
- data/app/models/tr8n/translation_key.rb +29 -13
- data/app/models/tr8n/translation_key_source.rb +0 -1
- data/app/models/tr8n/translation_source.rb +5 -5
- data/app/models/tr8n/translation_source_language.rb +39 -0
- data/app/models/tr8n/translator.rb +2 -11
- data/app/views/tr8n/common/_language_strip.html.erb +1 -1
- data/app/views/tr8n/common/_scripts.html.erb +3 -4
- data/app/views/tr8n/help/lb_shortcuts.html.erb +23 -22
- data/app/views/tr8n/help/lb_stats.html.erb +63 -0
- data/bin/tr8n.rb +24 -0
- data/db/migrate/20100405201417_create_tr8n_tables.rb +1 -1
- data/db/migrate/20111003194443_create_tr8n_sync_tables.rb +23 -0
- data/db/migrate/20111011013640_add_remote_id_to_tr8n_translators.rb +23 -0
- data/db/migrate/20111026230545_create_tr8n_translation_source_languages.rb +34 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/config.yml +18 -14
- data/{config → lib/generators/tr8n/templates/config}/tr8n/data/ip_locations.csv +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/rules/default_date_rules.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/rules/default_gender_list_rules.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/rules/default_gender_rules.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/rules/default_language_cases.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/rules/default_list_rules.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/rules/default_numeric_rules.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/rules/default_value_rules.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/site/default_glossary.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/site/default_languages.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/site/features.yml +1 -6
- data/{config → lib/generators/tr8n/templates/config}/tr8n/site/shortcuts.yml +4 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/site/sitemap.json +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/tokens/data.yml +0 -0
- data/{config → lib/generators/tr8n/templates/config}/tr8n/tokens/decorations.yml +0 -0
- data/lib/generators/tr8n/templates/db/create_tr8n_tables.rb +77 -55
- data/lib/generators/tr8n/tr8n_generator.rb +1 -1
- data/lib/tr8n/cache.rb +109 -8
- data/lib/tr8n/config.rb +14 -4
- data/lib/tr8n/extensions/action_controller_extension.rb +36 -38
- data/lib/tr8n/extensions/action_view_extension.rb +3 -17
- data/lib/tr8n/extensions/date_extension.rb +0 -1
- data/lib/tr8n/extensions/hash_extension.rb +66 -0
- data/lib/tr8n/extensions/string_extension.rb +1 -1
- data/lib/tr8n/extensions/time_extension.rb +0 -1
- data/lib/tr8n/version.rb +1 -1
- data/local/tr8n_server/app/views/layouts/_footer.html.erb +1 -1
- data/local/tr8n_server/config/tr8n/config.yml +18 -14
- data/local/tr8n_server/config/tr8n/site/features.yml +1 -6
- data/local/tr8n_server/config/tr8n/site/shortcuts.yml +4 -0
- data/local/tr8n_server/db/migrate/20110930041150_create_tr8n_tables.rb +78 -56
- data/local/tr8n_server/db/schema.rb +10 -1
- metadata +56 -61
- data/app/views/tr8n/help/lb_credits.html.erb +0 -9
- data/local/tr8n_server/app/views/layouts/tr8n.html.erb +0 -51
- data/local/tr8n_server/app/views/layouts/tr8n_admin.html.erb +0 -61
- data/local/tr8n_server/db/migrate/20111003194443_create_tr8n_sync_tables.rb +0 -22
- data/local/tr8n_server/db/migrate/20111011013640_add_remote_id_to_tr8n_translators.rb +0 -5
data/.gitignore
CHANGED
data/.rvmrc
CHANGED
@@ -1 +1 @@
|
|
1
|
-
rvm 1.9.2 --create
|
1
|
+
rvm 1.9.2@tr8n --create
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
tr8n (3.1.
|
4
|
+
tr8n (3.1.6)
|
5
5
|
coffee-script
|
6
6
|
kaminari
|
7
7
|
rails (>= 3.1.0)
|
@@ -56,7 +56,7 @@ GEM
|
|
56
56
|
coffee-script (2.2.0)
|
57
57
|
coffee-script-source
|
58
58
|
execjs
|
59
|
-
coffee-script-source (1.1.
|
59
|
+
coffee-script-source (1.1.3)
|
60
60
|
database_cleaner (0.6.7)
|
61
61
|
diff-lcs (1.1.3)
|
62
62
|
erubis (2.7.0)
|
@@ -80,7 +80,7 @@ GEM
|
|
80
80
|
mime-types (1.16)
|
81
81
|
multi_json (1.0.3)
|
82
82
|
nokogiri (1.5.0)
|
83
|
-
polyglot (0.3.
|
83
|
+
polyglot (0.3.3)
|
84
84
|
pry (0.9.6.2)
|
85
85
|
coderay (~> 0.9.8)
|
86
86
|
method_source (~> 0.6.5)
|
@@ -129,7 +129,7 @@ GEM
|
|
129
129
|
ruby_parser (2.0.6)
|
130
130
|
sexp_processor (~> 3.0)
|
131
131
|
rubyzip (0.9.4)
|
132
|
-
sass (3.1.
|
132
|
+
sass (3.1.10)
|
133
133
|
selenium-webdriver (2.7.0)
|
134
134
|
childprocess (>= 0.2.1)
|
135
135
|
ffi (>= 1.0.7)
|
@@ -150,7 +150,7 @@ GEM
|
|
150
150
|
treetop (1.4.10)
|
151
151
|
polyglot
|
152
152
|
polyglot (>= 0.3.1)
|
153
|
-
tzinfo (0.3.
|
153
|
+
tzinfo (0.3.31)
|
154
154
|
will_filter (3.1.3)
|
155
155
|
coffee-script
|
156
156
|
kaminari
|
data/README.rdoc
CHANGED
@@ -8,6 +8,8 @@ The language specific context and case rules can be registered and managed for a
|
|
8
8
|
provides a set of powerful administration tools that allow admins to manage any aspect of the engine; enabling and disabling its features
|
9
9
|
and monitoring translation progress.
|
10
10
|
|
11
|
+
http://img507.imageshack.us/img507/2876/tr8nlogo.png
|
12
|
+
|
11
13
|
The Tr8n engine itself is based on a very robust and flexible pluggable architecture where rule types and the syntax of the "tr" tokens
|
12
14
|
can be configured or extended for any application deployment.
|
13
15
|
|
@@ -21,21 +23,34 @@ You can visit their web sites and see how it is being used. If your company is u
|
|
21
23
|
|
22
24
|
= Documentation
|
23
25
|
|
24
|
-
|
26
|
+
Configuration Guide
|
27
|
+
|
28
|
+
https://github.com/berk/tr8n/wiki/4.-Configuration-Instructions
|
29
|
+
|
30
|
+
Integration Guide
|
31
|
+
|
32
|
+
https://github.com/berk/tr8n/wiki/5.-Integration-Instructions
|
33
|
+
|
34
|
+
Label Internationalization
|
35
|
+
|
36
|
+
https://github.com/berk/tr8n/wiki/6.-Tr8n-Syntax
|
25
37
|
|
26
|
-
|
38
|
+
Rules Engine
|
27
39
|
|
28
|
-
Tr8n
|
40
|
+
https://github.com/berk/tr8n/wiki/7.-Tr8n-Rules-Engine
|
29
41
|
|
30
|
-
|
42
|
+
Language Context Rules
|
31
43
|
|
32
|
-
|
44
|
+
https://github.com/berk/tr8n/wiki/7.1-Language-Context-Rules
|
33
45
|
|
34
|
-
|
46
|
+
Language Case Rules
|
35
47
|
|
36
|
-
|
48
|
+
https://github.com/berk/tr8n/wiki/7.2-Language-Case-Rules
|
49
|
+
|
50
|
+
Supported Languages
|
51
|
+
|
52
|
+
https://github.com/berk/tr8n/wiki/9.-Supported-Languages
|
37
53
|
|
38
|
-
http://wiki.tr8n.org/index.php?title=Tr8n_Languages
|
39
54
|
|
40
55
|
= Installation Instructions
|
41
56
|
|
@@ -92,35 +107,35 @@ Below are a few screenshots of what Tr8n looks like:
|
|
92
107
|
|
93
108
|
== Tr8n Language Selector (in a lightbox)
|
94
109
|
|
95
|
-
http://
|
110
|
+
http://img853.imageshack.us/img853/6784/tr8n1.png
|
96
111
|
|
97
112
|
== Tr8n Translation Interface
|
98
113
|
|
99
|
-
http://
|
114
|
+
http://img140.imageshack.us/img140/1272/tr8n2.png
|
100
115
|
|
101
116
|
== Tr8n Translation Votes Interface
|
102
117
|
|
103
|
-
http://
|
118
|
+
http://img854.imageshack.us/img854/1341/tr8n3.png
|
104
119
|
|
105
120
|
== Tr8n Language Selector (as a dropdown)
|
106
121
|
|
107
|
-
http://
|
122
|
+
http://img233.imageshack.us/img233/3973/tr8n4.png
|
108
123
|
|
109
124
|
== Tr8n Translation Interface (with a keyboard)
|
110
125
|
|
111
|
-
http://
|
126
|
+
http://img717.imageshack.us/img717/9392/tr8n6.png
|
112
127
|
|
113
128
|
== Tr8n Translation Tools
|
114
129
|
|
115
|
-
http://
|
130
|
+
http://img824.imageshack.us/img824/2263/tr8n8.png
|
116
131
|
|
117
132
|
== Tr8n Translator Dashboard
|
118
133
|
|
119
|
-
http://
|
134
|
+
http://img337.imageshack.us/img337/3180/tr8n5.png
|
120
135
|
|
121
136
|
== Tr8n Translation Admin Tools
|
122
137
|
|
123
|
-
http://
|
138
|
+
http://img225.imageshack.us/img225/3599/tr8n7.png
|
124
139
|
|
125
140
|
|
126
141
|
= External Links
|
@@ -138,12 +153,16 @@ Geni Goes Global With 20 New Languages And A Crowdsourced Translation Tool
|
|
138
153
|
|
139
154
|
http://tcrn.ch/f1VLnj
|
140
155
|
|
141
|
-
|
142
156
|
Quora Discussion - What is the best way to deal with internationlization of text on a large social site?
|
143
157
|
|
144
158
|
http://bit.ly/hUU6R9
|
145
159
|
|
146
160
|
|
161
|
+
LinkedIn Discussion
|
162
|
+
|
163
|
+
http://www.linkedin.com/groups/Internationalizing-your-application-using-Tr8n-4090552?gid=4090552
|
164
|
+
|
165
|
+
|
147
166
|
RailsCasts - If you would like to see a RailsCasts episode on how to get Tr8n configured and running, please visit the RailsCasts suggestion page and vote it up. Thank you!
|
148
167
|
|
149
168
|
http://bit.ly/gz7lFw
|
@@ -94,6 +94,7 @@ Tr8n.Translator = function(options) {
|
|
94
94
|
var self = this;
|
95
95
|
this.options = options;
|
96
96
|
this.translation_key_id = null;
|
97
|
+
this.suggestion_tokens = null;
|
97
98
|
|
98
99
|
this.container = document.createElement('div');
|
99
100
|
this.container.className = 'tr8n_translator';
|
@@ -291,20 +292,35 @@ Tr8n.Translator.prototype = {
|
|
291
292
|
});
|
292
293
|
},
|
293
294
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
Tr8n.
|
303
|
-
Tr8n.element("tr8n_google_suggestion_container_" + translation_key_id).style.display = "block";
|
304
|
-
var suggestion_section = Tr8n.element('tr8n_google_suggestion_section');
|
305
|
-
if (suggestion_section) suggestion_section.style.display = "block";
|
295
|
+
processSuggestedTranslation: function(response) {
|
296
|
+
if (response == null ||response.data == null || response.data.translations==null || response.data.translations.length == 0)
|
297
|
+
return;
|
298
|
+
var suggestion = response.data.translations[0].translatedText;
|
299
|
+
if (this.suggestion_tokens) {
|
300
|
+
var tokens = this.suggestion_tokens.split(",");
|
301
|
+
this.suggestion_tokens = null;
|
302
|
+
for (var i=0; i<tokens.length; i++) {
|
303
|
+
suggestion = Tr8n.Utils.replaceAll(suggestion, "(" + i + ")", tokens[i]);
|
306
304
|
}
|
307
|
-
}
|
305
|
+
}
|
306
|
+
Tr8n.element("tr8n_translation_suggestion_" + this.translation_key_id).innerHTML = suggestion;
|
307
|
+
Tr8n.element("tr8n_google_suggestion_container_" + this.translation_key_id).style.display = "block";
|
308
|
+
var suggestion_section = Tr8n.element('tr8n_google_suggestion_section');
|
309
|
+
if (suggestion_section) suggestion_section.style.display = "block";
|
310
|
+
},
|
311
|
+
|
312
|
+
suggestTranslation: function(translation_key_id, original, tokens, from_lang, to_lang) {
|
313
|
+
if (Tr8n.google_api_key == null) return;
|
314
|
+
|
315
|
+
this.suggestion_tokens = tokens;
|
316
|
+
this.translation_key_id = translation_key_id;
|
317
|
+
var new_script = document.createElement('script');
|
318
|
+
new_script.type = 'text/javascript';
|
319
|
+
var source_text = escape(original);
|
320
|
+
var api_source = 'https://www.googleapis.com/language/translate/v2?key=' + Tr8n.google_api_key;
|
321
|
+
var source = api_source + '&source=' + from_lang + '&target=' + to_lang + '&callback=tr8nTranslator.processSuggestedTranslation&q=' + source_text;
|
322
|
+
new_script.src = source;
|
323
|
+
document.getElementsByTagName('head')[0].appendChild(new_script);
|
308
324
|
}
|
309
325
|
|
310
326
|
}
|
@@ -851,9 +867,9 @@ Tr8n.Utils = {
|
|
851
867
|
tr8nLightbox.show('/tr8n/help/lb_shortcuts', {width:400, height:480});
|
852
868
|
},
|
853
869
|
|
854
|
-
|
870
|
+
displayStatistics: function() {
|
855
871
|
if (tr8nLightbox)
|
856
|
-
tr8nLightbox.show('/tr8n/help/
|
872
|
+
tr8nLightbox.show('/tr8n/help/lb_stats', {width:420, height:400});
|
857
873
|
}
|
858
874
|
|
859
875
|
}
|
@@ -886,7 +902,3 @@ function initializeTr8n() {
|
|
886
902
|
|
887
903
|
Tr8n.Utils.addEvent(window, 'load', setup);
|
888
904
|
}
|
889
|
-
|
890
|
-
function initializeTr8nGoogleSuggestions() {
|
891
|
-
google.load("language", "1");
|
892
|
-
}
|
@@ -23,7 +23,9 @@
|
|
23
23
|
|
24
24
|
class Tr8n::HelpController < Tr8n::BaseController
|
25
25
|
|
26
|
-
before_filter :validate_current_translator
|
26
|
+
before_filter :validate_current_translator, :except => [:lb_shortcuts, :lb_stats, :credits, :license]
|
27
|
+
before_filter :validate_guest_user, :except => [:lb_shortcuts, :lb_stats, :credits, :license]
|
28
|
+
before_filter :validate_current_user, :except => [:lb_shortcuts, :lb_stats, :credits, :license]
|
27
29
|
|
28
30
|
def index
|
29
31
|
|
@@ -33,8 +35,16 @@ class Tr8n::HelpController < Tr8n::BaseController
|
|
33
35
|
render :layout => false
|
34
36
|
end
|
35
37
|
|
36
|
-
def
|
38
|
+
def lb_stats
|
37
39
|
render :layout => false
|
38
40
|
end
|
41
|
+
|
42
|
+
def credits
|
43
|
+
|
44
|
+
end
|
39
45
|
|
46
|
+
def license
|
47
|
+
|
48
|
+
end
|
49
|
+
|
40
50
|
end
|
data/app/models/tr8n/language.rb
CHANGED
@@ -24,8 +24,8 @@
|
|
24
24
|
class Tr8n::Language < ActiveRecord::Base
|
25
25
|
set_table_name :tr8n_languages
|
26
26
|
|
27
|
-
after_save :
|
28
|
-
after_destroy :
|
27
|
+
after_save :update_cache
|
28
|
+
after_destroy :update_cache
|
29
29
|
|
30
30
|
belongs_to :fallback_language, :class_name => 'Tr8n::Language', :foreign_key => :fallback_language_id
|
31
31
|
|
@@ -303,7 +303,11 @@ class Tr8n::Language < ActiveRecord::Base
|
|
303
303
|
true
|
304
304
|
end
|
305
305
|
|
306
|
-
def
|
306
|
+
def translations_changed!
|
307
|
+
# TODO: handle change event - count translations, update total metrics
|
308
|
+
end
|
309
|
+
|
310
|
+
def update_cache
|
307
311
|
Tr8n::Cache.delete("language_#{locale}")
|
308
312
|
Tr8n::Cache.delete("featured_languages")
|
309
313
|
Tr8n::Cache.delete("enabled_languages")
|
@@ -23,8 +23,8 @@
|
|
23
23
|
|
24
24
|
class Tr8n::Translation < ActiveRecord::Base
|
25
25
|
set_table_name :tr8n_translations
|
26
|
-
after_save :
|
27
|
-
after_destroy :
|
26
|
+
after_save :update_cache
|
27
|
+
after_destroy :update_cache
|
28
28
|
|
29
29
|
belongs_to :language, :class_name => "Tr8n::Language"
|
30
30
|
belongs_to :translation_key, :class_name => "Tr8n::TranslationKey"
|
@@ -86,11 +86,14 @@ class Tr8n::Translation < ActiveRecord::Base
|
|
86
86
|
|
87
87
|
# populate language rules from the internal rules hash
|
88
88
|
def rules
|
89
|
-
|
90
|
-
|
89
|
+
super_rules = super
|
90
|
+
return nil if super_rules == nil
|
91
|
+
return nil unless super_rules.class.name == 'Array'
|
92
|
+
return nil if super_rules.size == 0
|
93
|
+
|
91
94
|
@loaded_rules ||= begin
|
92
95
|
rulz = []
|
93
|
-
|
96
|
+
super_rules.each do |rule|
|
94
97
|
[rule[:rule_id]].flatten.each do |rule_id|
|
95
98
|
language_rule = Tr8n::LanguageRule.by_id(rule_id)
|
96
99
|
rulz << rule.merge({:rule => language_rule}) if language_rule
|
@@ -248,9 +251,9 @@ class Tr8n::Translation < ActiveRecord::Base
|
|
248
251
|
destroy
|
249
252
|
end
|
250
253
|
|
251
|
-
def
|
252
|
-
|
253
|
-
translation_key.
|
254
|
+
def update_cache
|
255
|
+
language.translations_changed!
|
256
|
+
translation_key.translations_changed!(language)
|
254
257
|
end
|
255
258
|
|
256
259
|
###############################################################
|
@@ -34,7 +34,7 @@ class Tr8n::TranslationDomain < ActiveRecord::Base
|
|
34
34
|
alias :key_sources :translation_key_sources
|
35
35
|
alias :keys :translation_keys
|
36
36
|
|
37
|
-
def self.find_or_create(url)
|
37
|
+
def self.find_or_create(url = nil)
|
38
38
|
domain_name = URI.parse(url || 'localhost').host || 'localhost'
|
39
39
|
Tr8n::Cache.fetch("translation_domain_#{domain_name}") do
|
40
40
|
find_by_name(domain_name) || create(:name => domain_name)
|
@@ -109,12 +109,12 @@ class Tr8n::TranslationKey < ActiveRecord::Base
|
|
109
109
|
# primarely used for the site map and only needs to be enabled
|
110
110
|
# for a short period of time on a single machine
|
111
111
|
def self.track_source(tkey, options)
|
112
|
-
return unless Tr8n::Config.enable_key_source_tracking?
|
113
|
-
return if options[:source].blank?
|
112
|
+
# return unless Tr8n::Config.enable_key_source_tracking?
|
113
|
+
# return if options[:source].blank?
|
114
|
+
|
115
|
+
key_source = Tr8n::Cache.cache_key_source(tkey, options[:source] || Tr8n::Config.block_options[:source])
|
114
116
|
|
115
|
-
key_source = Tr8n::TranslationKeySource.find_or_create(tkey, Tr8n::TranslationSource.find_or_create(options[:source], options[:url]))
|
116
117
|
return unless Tr8n::Config.enable_key_caller_tracking?
|
117
|
-
|
118
118
|
options[:caller] ||= caller
|
119
119
|
options[:caller_key] = options[:caller].is_a?(Array) ? options[:caller].join(", ") : options[:caller].to_s
|
120
120
|
options[:caller_key] = generate_key(options[:caller_key])
|
@@ -236,10 +236,18 @@ class Tr8n::TranslationKey < ActiveRecord::Base
|
|
236
236
|
def inline_translations_for(language)
|
237
237
|
translations_for(language, -50)
|
238
238
|
end
|
239
|
+
|
240
|
+
def translations_cache_key(language)
|
241
|
+
"translations_#{language.locale}_#{key}"
|
242
|
+
end
|
243
|
+
|
244
|
+
def clear_translations_cache_for_language(language = Tr8n::Config.current_language)
|
245
|
+
Tr8n::Cache.delete(translations_cache_key(language))
|
246
|
+
end
|
239
247
|
|
240
248
|
# returns only the translations that meet the minimum rank
|
241
|
-
def
|
242
|
-
Tr8n::Cache.fetch(
|
249
|
+
def valid_translations_for_language(language = Tr8n::Config.current_language)
|
250
|
+
Tr8n::Cache.fetch(translations_cache_key(language)) do
|
243
251
|
translations_for(language, Tr8n::Config.translation_threshold)
|
244
252
|
end
|
245
253
|
end
|
@@ -333,7 +341,7 @@ class Tr8n::TranslationKey < ActiveRecord::Base
|
|
333
341
|
|
334
342
|
def find_first_valid_translation(language, token_values)
|
335
343
|
# find the first translation in the order of the rank that matches the rules
|
336
|
-
|
344
|
+
valid_translations_for_language(language).each do |translation|
|
337
345
|
return translation if translation.matches_rules?(token_values)
|
338
346
|
end
|
339
347
|
|
@@ -372,7 +380,7 @@ class Tr8n::TranslationKey < ActiveRecord::Base
|
|
372
380
|
end
|
373
381
|
|
374
382
|
def translate(language = Tr8n::Config.current_language, token_values = {}, options = {})
|
375
|
-
return find_all_valid_translations(
|
383
|
+
return find_all_valid_translations(valid_translations_for_language(language)) if options[:api]
|
376
384
|
|
377
385
|
if Tr8n::Config.disabled? or language.default?
|
378
386
|
return substitute_tokens(label, token_values, options.merge(:fallback => false), language).html_safe
|
@@ -436,7 +444,7 @@ class Tr8n::TranslationKey < ActiveRecord::Base
|
|
436
444
|
|
437
445
|
classes = ['tr8n_translatable']
|
438
446
|
|
439
|
-
if
|
447
|
+
if valid_translations_for_language(language).any?
|
440
448
|
classes << 'tr8n_translated'
|
441
449
|
else
|
442
450
|
classes << 'tr8n_not_translated'
|
@@ -486,6 +494,18 @@ class Tr8n::TranslationKey < ActiveRecord::Base
|
|
486
494
|
update_attributes(:verified_at => time)
|
487
495
|
end
|
488
496
|
|
497
|
+
def translations_changed!(language = Tr8n::Config.current_language)
|
498
|
+
clear_translations_cache_for_language(language)
|
499
|
+
|
500
|
+
# update timestamp and clear cache
|
501
|
+
update_translation_count!
|
502
|
+
|
503
|
+
# notify all language sources that translation has changed
|
504
|
+
sources.each do |source|
|
505
|
+
Tr8n::TranslationSourceLanguage.touch(source, language)
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
489
509
|
def update_translation_count!
|
490
510
|
update_attributes(:translation_count => Tr8n::Translation.count(:conditions => ["translation_key_id = ?", self.id]))
|
491
511
|
end
|
@@ -504,10 +524,6 @@ class Tr8n::TranslationKey < ActiveRecord::Base
|
|
504
524
|
Tr8n::Cache.delete("translation_key_#{key}")
|
505
525
|
end
|
506
526
|
|
507
|
-
def add_translation(label, rules = nil, lang = Tr8n::Config.current_language, translator = Tr8n::Config.current_translator)
|
508
|
-
Tr8n::Translation.create(:translation_key => self, :label => label, :language => lang, :translator => translator)
|
509
|
-
end
|
510
|
-
|
511
527
|
def to_api_hash
|
512
528
|
{
|
513
529
|
:key => self.key,
|
@@ -23,19 +23,19 @@
|
|
23
23
|
|
24
24
|
class Tr8n::TranslationSource < ActiveRecord::Base
|
25
25
|
set_table_name :tr8n_translation_sources
|
26
|
-
after_save :clear_cache
|
27
26
|
after_destroy :clear_cache
|
28
27
|
|
29
|
-
belongs_to :translation_domain,
|
28
|
+
belongs_to :translation_domain, :class_name => "Tr8n::TranslationDomain"
|
30
29
|
|
31
|
-
has_many :translation_key_sources,
|
32
|
-
has_many :translation_keys,
|
30
|
+
has_many :translation_key_sources, :class_name => "Tr8n::TranslationKeySource", :dependent => :destroy
|
31
|
+
has_many :translation_keys, :class_name => "Tr8n::TranslationKey", :through => :translation_key_sources
|
32
|
+
has_many :translation_source_languages, :class_name => "Tr8n::TranslationSourceLanguage"
|
33
33
|
|
34
34
|
alias :domain :translation_domain
|
35
35
|
alias :sources :translation_key_sources
|
36
36
|
alias :keys :translation_keys
|
37
37
|
|
38
|
-
def self.find_or_create(source, url)
|
38
|
+
def self.find_or_create(source, url = nil)
|
39
39
|
translation_domain = Tr8n::TranslationDomain.find_or_create(url)
|
40
40
|
Tr8n::Cache.fetch("translation_source_#{translation_domain.id}_#{source}") do
|
41
41
|
translation_source = where("source = ? and translation_domain_id = ?", source, translation_domain.id).first
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010-2011 Michael Berkovich, tr8n.net
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
class Tr8n::TranslationSourceLanguage < ActiveRecord::Base
|
25
|
+
set_table_name :tr8n_translation_source_languages
|
26
|
+
|
27
|
+
belongs_to :translation_source, :class_name => "Tr8n::TranslationSource"
|
28
|
+
belongs_to :language, :class_name => "Tr8n::Language"
|
29
|
+
|
30
|
+
def self.find_or_create(translation_source, language = Tr8n::Config.current_language)
|
31
|
+
source_lang = where("translation_source_id = ? and language_id = ?", translation_source.id, language.id).first
|
32
|
+
source_lang ||= create(:translation_source => translation_source, :language => language)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.touch(translation_source, language = Tr8n::Config.current_language)
|
36
|
+
find_or_create(translation_source, language).touch
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -23,8 +23,6 @@
|
|
23
23
|
|
24
24
|
class Tr8n::Translator < ActiveRecord::Base
|
25
25
|
set_table_name :tr8n_translators
|
26
|
-
after_save :clear_cache
|
27
|
-
after_destroy :clear_cache
|
28
26
|
|
29
27
|
belongs_to :user, :class_name => Tr8n::Config.user_class_name, :foreign_key => :user_id
|
30
28
|
|
@@ -46,10 +44,7 @@ class Tr8n::Translator < ActiveRecord::Base
|
|
46
44
|
return nil unless user and user.id
|
47
45
|
return nil if Tr8n::Config.guest_user?(user)
|
48
46
|
return user if user.is_a?(Tr8n::Translator)
|
49
|
-
|
50
|
-
Tr8n::Cache.fetch("translator_for_#{user.id}") do
|
51
|
-
find_by_user_id(user.id)
|
52
|
-
end
|
47
|
+
find_by_user_id(user.id)
|
53
48
|
end
|
54
49
|
|
55
50
|
def self.find_or_create(user)
|
@@ -123,7 +118,7 @@ class Tr8n::Translator < ActiveRecord::Base
|
|
123
118
|
|
124
119
|
def switched_language!(language)
|
125
120
|
lu = Tr8n::LanguageUser.create_or_touch(user || self, language)
|
126
|
-
lu.update_attributes(:
|
121
|
+
lu.update_attributes(:translator_id => self.id) unless lu.translator
|
127
122
|
Tr8n::TranslatorLog.log(self, :switched_language, language.id)
|
128
123
|
end
|
129
124
|
|
@@ -305,10 +300,6 @@ class Tr8n::Translator < ActiveRecord::Base
|
|
305
300
|
# update_attributes(:last_ip => new_ip, :country_code => (ipl? ? ipl.ctry : nil))
|
306
301
|
end
|
307
302
|
|
308
|
-
def clear_cache
|
309
|
-
Tr8n::Cache.delete("translator_for_#{user_id}")
|
310
|
-
end
|
311
|
-
|
312
303
|
def to_s
|
313
304
|
name
|
314
305
|
end
|
@@ -13,11 +13,10 @@
|
|
13
13
|
<%=javascript_include_tag(Tr8n::Config.effects_library_path) -%>
|
14
14
|
<% end %>
|
15
15
|
|
16
|
-
<% if Tr8n::Config.enable_google_suggestions? and Tr8n::Config.current_user_is_translator? %>
|
17
|
-
<script type="text/javascript" src="<%=request.ssl? ? 'https' : 'http' %>://www.google.com/jsapi"></script>
|
16
|
+
<% if Tr8n::Config.enable_google_suggestions? and Tr8n::Config.current_user_is_translator? %>
|
18
17
|
<script type="text/javascript">
|
19
|
-
|
20
|
-
|
18
|
+
Tr8n.google_api_key = "<%=Tr8n::Config.google_api_key %>";
|
19
|
+
</script>
|
21
20
|
<% end %>
|
22
21
|
|
23
22
|
<% if Tr8n::Config.enable_software_keyboard? %>
|
@@ -1,26 +1,27 @@
|
|
1
|
-
<div
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
<div class="inner">
|
2
|
+
<div class="hd">
|
3
|
+
<span style="float:right;">
|
4
|
+
<%=link_to_function(image_tag("tr8n/close.gif"), "tr8nLightbox.hide();")%>
|
5
|
+
</span>
|
6
|
+
<%=trl("Tr8n Translation Engine Shortcuts")%>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="bd" style="background-color:white;">
|
10
|
+
<div style="overflow:auto;max-height:450px;">
|
11
|
+
<table style="width:100%" celppading="0px" cellspacing="0px">
|
12
|
+
<tr>
|
13
|
+
<td style="font-size:12px; font-weight:bold; padding:5px; border-bottom:1px solid #ccc; text-align:left;"><%=trl("Key", "Shortcut key combination")%></td>
|
14
|
+
<td style="font-size:12px; font-weight:bold; padding:5px; border-bottom:1px solid #ccc; text-align:left;"><%=trl("Description", "Shortcut key description")%></td>
|
15
|
+
</tr>
|
10
16
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
<% Tr8n::Config.default_shortcuts.keys.sort.each do |key| %>
|
18
|
+
<tr>
|
19
|
+
<td style="font-size:10px; padding:5px;border-bottom:1px dotted #ccc; text-align:left;"><%=key%></td>
|
20
|
+
<td style="font-size:10px; padding:5px;border-bottom:1px dotted #ccc; text-align:left;"><%=Tr8n::Config.default_shortcuts[key][:description]%></td>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
17
23
|
|
18
|
-
|
24
|
+
</table>
|
25
|
+
</div>
|
19
26
|
</div>
|
20
27
|
</div>
|
21
|
-
|
22
|
-
<div class="buttons_container" style="text-align:center;">
|
23
|
-
<button type="submit" class="translator_btn translator_submit_btn" onClick="tr8nLightbox.hide(); return false;">
|
24
|
-
<span><%=trl("Close", "Lightbox close button")%></span>
|
25
|
-
</button>
|
26
|
-
</div>
|