mirror of
https://github.com/discourse/discourse.git
synced 2025-02-07 11:58:27 +00:00
Add message format support that can be used on complex localization strings
Add message about new and unread topics at the bottom of topics move localization helper into lib
This commit is contained in:
parent
e93b7a3b20
commit
8874c9ea75
@ -101,7 +101,7 @@
|
||||
</table>
|
||||
</div>
|
||||
<br/>
|
||||
<h3>{{{unbound view.browseMoreMessage}}}</h3>
|
||||
<h3>{{{view.browseMoreMessage}}}</h3>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
@ -440,20 +440,41 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, {
|
||||
}
|
||||
},
|
||||
|
||||
topicTrackingState: function(){
|
||||
return Discourse.TopicTrackingState.current();
|
||||
}.property(),
|
||||
|
||||
browseMoreMessage: (function() {
|
||||
var category, opts;
|
||||
|
||||
opts = {
|
||||
latestLink: "<a href=\"/\">" + (Em.String.i18n("topic.view_latest_topics")) + "</a>"
|
||||
};
|
||||
|
||||
if (category = this.get('controller.content.category')) {
|
||||
opts.catLink = Discourse.Utilities.categoryLink(category);
|
||||
return Ember.String.i18n("topic.read_more_in_category", opts);
|
||||
} else {
|
||||
opts.catLink = "<a href=\"" + Discourse.getURL("/categories") + "\">" + (Em.String.i18n("topic.browse_all_categories")) + "</a>";
|
||||
}
|
||||
|
||||
var tracking = this.get('topicTrackingState');
|
||||
|
||||
var unreadTopics = tracking.countUnread();
|
||||
var newTopics = tracking.countNew();
|
||||
|
||||
if (newTopics + unreadTopics > 0) {
|
||||
if(category) {
|
||||
return I18n.messageFormat("topic.read_more_in_category_MF", {"UNREAD": unreadTopics, "NEW": newTopics, catLink: opts.catLink})
|
||||
} else {
|
||||
return I18n.messageFormat("topic.read_more_MF", {"UNREAD": unreadTopics, "NEW": newTopics, latestLink: opts.latestLink})
|
||||
}
|
||||
}
|
||||
else if (category) {
|
||||
return Ember.String.i18n("topic.read_more_in_category", opts);
|
||||
} else {
|
||||
return Ember.String.i18n("topic.read_more", opts);
|
||||
}
|
||||
}).property()
|
||||
}).property('topicTrackingState.messageCount')
|
||||
|
||||
});
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
module JsLocaleHelper
|
||||
|
||||
def self.output_locale(locale)
|
||||
|
||||
locale_str = locale.to_s
|
||||
|
||||
translations = YAML::load(File.open("#{Rails.root}/config/locales/client.#{locale_str}.yml"))
|
||||
|
||||
# We used to split the admin versus the client side, but it's much simpler to just
|
||||
# include both for now due to the small size of the admin section.
|
||||
#
|
||||
# For now, let's leave it split out in the translation file in case we want to split
|
||||
# it again later, so we'll merge the JSON ourselves.
|
||||
admin_contents = translations[locale_str].delete('admin_js')
|
||||
|
||||
translations[locale_str]['js'].merge!(admin_contents) if admin_contents.present?
|
||||
|
||||
result = "I18n.translations = #{translations.to_json};\n"
|
||||
result << "I18n.locale = '#{locale_str}'\n"
|
||||
result
|
||||
end
|
||||
|
||||
end
|
@ -19,6 +19,7 @@ module Discourse
|
||||
# -- all .rb files in that directory are automatically loaded.
|
||||
|
||||
require 'discourse'
|
||||
require 'js_locale_helper'
|
||||
|
||||
# mocha hates us, active_support/testing/mochaing.rb line 2 is requiring the wrong
|
||||
# require, patched in source, on upgrade remove this
|
||||
|
@ -505,6 +505,11 @@ en:
|
||||
toggle_information: "toggle topic details"
|
||||
read_more_in_category: "Want to read more? Browse other topics in {{catLink}} or {{latestLink}}."
|
||||
read_more: "Want to read more? {{catLink}} or {{latestLink}}."
|
||||
|
||||
# keys ending with _MF use message format, see /spec/components/js_local_helper_spec.rb for samples
|
||||
read_more_in_category_MF: "There {UNREAD, plural, one {is <a href='/unread'>1 unread</a>} other {are <a href='/unread'># unread</a>}} and {NEW, plural, one {<a href='/new'>1 new</a> topic} other {<a href='/new'># new</a> topics}} remaining, or browse other topics in {catLink}"
|
||||
read_more_MF: "There {UNREAD, plural, one {is <a href='/unread'>1 unread</a>} other {are <a href='/unread'># unread</a>}} and {NEW, plural, one {<a href='/new'>1 new</a> topic} other {<a href='/new'># new</a> topics}} remaining, or {latestLink}"
|
||||
|
||||
browse_all_categories: Browse all categories
|
||||
|
||||
view_latest_topics: view latest topics
|
||||
|
6
lib/javascripts/locale/af.js
Normal file
6
lib/javascripts/locale/af.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.af = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/am.js
Normal file
6
lib/javascripts/locale/am.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.am = function(n) {
|
||||
if (n === 0 || n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
18
lib/javascripts/locale/ar.js
Normal file
18
lib/javascripts/locale/ar.js
Normal file
@ -0,0 +1,18 @@
|
||||
MessageFormat.locale.ar = function(n) {
|
||||
if (n === 0) {
|
||||
return 'zero';
|
||||
}
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n == 2) {
|
||||
return 'two';
|
||||
}
|
||||
if ((n % 100) >= 3 && (n % 100) <= 10 && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
if ((n % 100) >= 11 && (n % 100) <= 99 && n == Math.floor(n)) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/bg.js
Normal file
6
lib/javascripts/locale/bg.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.bg = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/bn.js
Normal file
6
lib/javascripts/locale/bn.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.bn = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
18
lib/javascripts/locale/br.js
Normal file
18
lib/javascripts/locale/br.js
Normal file
@ -0,0 +1,18 @@
|
||||
MessageFormat.locale.br = function (n) {
|
||||
if (n === 0) {
|
||||
return 'zero';
|
||||
}
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n == 2) {
|
||||
return 'two';
|
||||
}
|
||||
if (n == 3) {
|
||||
return 'few';
|
||||
}
|
||||
if (n == 6) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/ca.js
Normal file
6
lib/javascripts/locale/ca.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.ca = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
9
lib/javascripts/locale/cs.js
Normal file
9
lib/javascripts/locale/cs.js
Normal file
@ -0,0 +1,9 @@
|
||||
MessageFormat.locale.cs = function (n) {
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n == 2 || n == 3 || n == 4) {
|
||||
return 'few';
|
||||
}
|
||||
return 'other';
|
||||
};
|
18
lib/javascripts/locale/cy.js
Normal file
18
lib/javascripts/locale/cy.js
Normal file
@ -0,0 +1,18 @@
|
||||
MessageFormat.locale.cy = function (n) {
|
||||
if (n === 0) {
|
||||
return 'zero';
|
||||
}
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n == 2) {
|
||||
return 'two';
|
||||
}
|
||||
if (n == 3) {
|
||||
return 'few';
|
||||
}
|
||||
if (n == 6) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/da.js
Normal file
6
lib/javascripts/locale/da.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.da = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/de.js
Normal file
6
lib/javascripts/locale/de.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.de = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/el.js
Normal file
6
lib/javascripts/locale/el.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.el = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/en.js
Normal file
6
lib/javascripts/locale/en.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.en = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/es.js
Normal file
6
lib/javascripts/locale/es.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.es = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/et.js
Normal file
6
lib/javascripts/locale/et.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.et = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/eu.js
Normal file
6
lib/javascripts/locale/eu.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.eu = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/fa.js
Normal file
3
lib/javascripts/locale/fa.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.fa = function ( n ) {
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/fi.js
Normal file
6
lib/javascripts/locale/fi.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.fi = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/fil.js
Normal file
6
lib/javascripts/locale/fil.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.fil = function(n) {
|
||||
if (n === 0 || n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/fr.js
Normal file
6
lib/javascripts/locale/fr.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.fr = function (n) {
|
||||
if (n >= 0 && n < 2) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
9
lib/javascripts/locale/ga.js
Normal file
9
lib/javascripts/locale/ga.js
Normal file
@ -0,0 +1,9 @@
|
||||
MessageFormat.locale.ga = function (n) {
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n == 2) {
|
||||
return 'two';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/gl.js
Normal file
6
lib/javascripts/locale/gl.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.gl = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/gsw.js
Normal file
6
lib/javascripts/locale/gsw.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.gsw = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/gu.js
Normal file
6
lib/javascripts/locale/gu.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.gu = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/he.js
Normal file
6
lib/javascripts/locale/he.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.he = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/hi.js
Normal file
6
lib/javascripts/locale/hi.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.hi = function(n) {
|
||||
if (n === 0 || n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
14
lib/javascripts/locale/hr.js
Normal file
14
lib/javascripts/locale/hr.js
Normal file
@ -0,0 +1,14 @@
|
||||
MessageFormat.locale.hr = function (n) {
|
||||
if ((n % 10) == 1 && (n % 100) != 11) {
|
||||
return 'one';
|
||||
}
|
||||
if ((n % 10) >= 2 && (n % 10) <= 4 &&
|
||||
((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
if ((n % 10) === 0 || ((n % 10) >= 5 && (n % 10) <= 9) ||
|
||||
((n % 100) >= 11 && (n % 100) <= 14) && n == Math.floor(n)) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
3
lib/javascripts/locale/hu.js
Normal file
3
lib/javascripts/locale/hu.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.hu = function(n) {
|
||||
return 'other';
|
||||
};
|
3
lib/javascripts/locale/id.js
Normal file
3
lib/javascripts/locale/id.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.id = function(n) {
|
||||
return 'other';
|
||||
};
|
3
lib/javascripts/locale/in.js
Normal file
3
lib/javascripts/locale/in.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale["in"] = function(n) {
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/is.js
Normal file
6
lib/javascripts/locale/is.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.is = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/it.js
Normal file
6
lib/javascripts/locale/it.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.it = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/iw.js
Normal file
6
lib/javascripts/locale/iw.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.iw = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/ja.js
Normal file
3
lib/javascripts/locale/ja.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.ja = function ( n ) {
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/kn.js
Normal file
3
lib/javascripts/locale/kn.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.kn = function ( n ) {
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/ko.js
Normal file
3
lib/javascripts/locale/ko.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.ko = function ( n ) {
|
||||
return "other";
|
||||
};
|
9
lib/javascripts/locale/lag.js
Normal file
9
lib/javascripts/locale/lag.js
Normal file
@ -0,0 +1,9 @@
|
||||
MessageFormat.locale.lag = function (n) {
|
||||
if (n === 0) {
|
||||
return 'zero';
|
||||
}
|
||||
if (n > 0 && n < 2) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/ln.js
Normal file
6
lib/javascripts/locale/ln.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.ln = function(n) {
|
||||
if (n === 0 || n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
10
lib/javascripts/locale/lt.js
Normal file
10
lib/javascripts/locale/lt.js
Normal file
@ -0,0 +1,10 @@
|
||||
MessageFormat.locale.lt = function (n) {
|
||||
if ((n % 10) == 1 && ((n % 100) < 11 || (n % 100) > 19)) {
|
||||
return 'one';
|
||||
}
|
||||
if ((n % 10) >= 2 && (n % 10) <= 9 &&
|
||||
((n % 100) < 11 || (n % 100) > 19) && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
return 'other';
|
||||
};
|
9
lib/javascripts/locale/lv.js
Normal file
9
lib/javascripts/locale/lv.js
Normal file
@ -0,0 +1,9 @@
|
||||
MessageFormat.locale.lv = function (n) {
|
||||
if (n === 0) {
|
||||
return 'zero';
|
||||
}
|
||||
if ((n % 10) == 1 && (n % 100) != 11) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/mk.js
Normal file
6
lib/javascripts/locale/mk.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.mk = function (n) {
|
||||
if ((n % 10) == 1 && n != 11) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/ml.js
Normal file
6
lib/javascripts/locale/ml.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.ml = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
10
lib/javascripts/locale/mo.js
Normal file
10
lib/javascripts/locale/mo.js
Normal file
@ -0,0 +1,10 @@
|
||||
MessageFormat.locale.mo = function (n) {
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n === 0 || n != 1 && (n % 100) >= 1 &&
|
||||
(n % 100) <= 19 && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/mr.js
Normal file
6
lib/javascripts/locale/mr.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.mr = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/ms.js
Normal file
3
lib/javascripts/locale/ms.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.ms = function ( n ) {
|
||||
return "other";
|
||||
};
|
12
lib/javascripts/locale/mt.js
Normal file
12
lib/javascripts/locale/mt.js
Normal file
@ -0,0 +1,12 @@
|
||||
MessageFormat.locale.mt = function (n) {
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n === 0 || ((n % 100) >= 2 && (n % 100) <= 4 && n == Math.floor(n))) {
|
||||
return 'few';
|
||||
}
|
||||
if ((n % 100) >= 11 && (n % 100) <= 19 && n == Math.floor(n)) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/nl.js
Normal file
6
lib/javascripts/locale/nl.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.nl = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/no.js
Normal file
6
lib/javascripts/locale/no.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.no = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/or.js
Normal file
6
lib/javascripts/locale/or.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.or = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
15
lib/javascripts/locale/pl.js
Normal file
15
lib/javascripts/locale/pl.js
Normal file
@ -0,0 +1,15 @@
|
||||
MessageFormat.locale.pl = function (n) {
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if ((n % 10) >= 2 && (n % 10) <= 4 &&
|
||||
((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
if ((n % 10) === 0 || n != 1 && (n % 10) == 1 ||
|
||||
((n % 10) >= 5 && (n % 10) <= 9 || (n % 100) >= 12 && (n % 100) <= 14) &&
|
||||
n == Math.floor(n)) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/pt.js
Normal file
6
lib/javascripts/locale/pt.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.pt = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
10
lib/javascripts/locale/ro.js
Normal file
10
lib/javascripts/locale/ro.js
Normal file
@ -0,0 +1,10 @@
|
||||
MessageFormat.locale.ro = function (n) {
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n === 0 || n != 1 && (n % 100) >= 1 &&
|
||||
(n % 100) <= 19 && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
return 'other';
|
||||
};
|
14
lib/javascripts/locale/ru.js
Normal file
14
lib/javascripts/locale/ru.js
Normal file
@ -0,0 +1,14 @@
|
||||
MessageFormat.locale.ru = function (n) {
|
||||
if ((n % 10) == 1 && (n % 100) != 11) {
|
||||
return 'one';
|
||||
}
|
||||
if ((n % 10) >= 2 && (n % 10) <= 4 &&
|
||||
((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
if ((n % 10) === 0 || ((n % 10) >= 5 && (n % 10) <= 9) ||
|
||||
((n % 100) >= 11 && (n % 100) <= 14) && n == Math.floor(n)) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
9
lib/javascripts/locale/shi.js
Normal file
9
lib/javascripts/locale/shi.js
Normal file
@ -0,0 +1,9 @@
|
||||
MessageFormat.locale.shi = function(n) {
|
||||
if (n >= 0 && n <= 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n >= 2 && n <= 10 && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
return 'other';
|
||||
};
|
9
lib/javascripts/locale/sk.js
Normal file
9
lib/javascripts/locale/sk.js
Normal file
@ -0,0 +1,9 @@
|
||||
MessageFormat.locale.sk = function (n) {
|
||||
if (n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if (n == 2 || n == 3 || n == 4) {
|
||||
return 'few';
|
||||
}
|
||||
return 'other';
|
||||
};
|
12
lib/javascripts/locale/sl.js
Normal file
12
lib/javascripts/locale/sl.js
Normal file
@ -0,0 +1,12 @@
|
||||
MessageFormat.locale.sl = function (n) {
|
||||
if ((n % 100) == 1) {
|
||||
return 'one';
|
||||
}
|
||||
if ((n % 100) == 2) {
|
||||
return 'two';
|
||||
}
|
||||
if ((n % 100) == 3 || (n % 100) == 4) {
|
||||
return 'few';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/sq.js
Normal file
6
lib/javascripts/locale/sq.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.sq = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
14
lib/javascripts/locale/sr.js
Normal file
14
lib/javascripts/locale/sr.js
Normal file
@ -0,0 +1,14 @@
|
||||
MessageFormat.locale.sr = function (n) {
|
||||
if ((n % 10) == 1 && (n % 100) != 11) {
|
||||
return 'one';
|
||||
}
|
||||
if ((n % 10) >= 2 && (n % 10) <= 4 &&
|
||||
((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
if ((n % 10) === 0 || ((n % 10) >= 5 && (n % 10) <= 9) ||
|
||||
((n % 100) >= 11 && (n % 100) <= 14) && n == Math.floor(n)) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/sv.js
Normal file
6
lib/javascripts/locale/sv.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.sv = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/sw.js
Normal file
6
lib/javascripts/locale/sw.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.sw = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/ta.js
Normal file
6
lib/javascripts/locale/ta.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.ta = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/te.js
Normal file
6
lib/javascripts/locale/te.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.te = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/th.js
Normal file
3
lib/javascripts/locale/th.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.th = function ( n ) {
|
||||
return "other";
|
||||
};
|
6
lib/javascripts/locale/tl.js
Normal file
6
lib/javascripts/locale/tl.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.tl = function(n) {
|
||||
if (n === 0 || n == 1) {
|
||||
return 'one';
|
||||
}
|
||||
return 'other';
|
||||
};
|
3
lib/javascripts/locale/tr.js
Normal file
3
lib/javascripts/locale/tr.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.tr = function(n) {
|
||||
return 'other';
|
||||
};
|
14
lib/javascripts/locale/uk.js
Normal file
14
lib/javascripts/locale/uk.js
Normal file
@ -0,0 +1,14 @@
|
||||
MessageFormat.locale.uk = function (n) {
|
||||
if ((n % 10) == 1 && (n % 100) != 11) {
|
||||
return 'one';
|
||||
}
|
||||
if ((n % 10) >= 2 && (n % 10) <= 4 &&
|
||||
((n % 100) < 12 || (n % 100) > 14) && n == Math.floor(n)) {
|
||||
return 'few';
|
||||
}
|
||||
if ((n % 10) === 0 || ((n % 10) >= 5 && (n % 10) <= 9) ||
|
||||
((n % 100) >= 11 && (n % 100) <= 14) && n == Math.floor(n)) {
|
||||
return 'many';
|
||||
}
|
||||
return 'other';
|
||||
};
|
6
lib/javascripts/locale/ur.js
Normal file
6
lib/javascripts/locale/ur.js
Normal file
@ -0,0 +1,6 @@
|
||||
MessageFormat.locale.ur = function ( n ) {
|
||||
if ( n === 1 ) {
|
||||
return "one";
|
||||
}
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/vi.js
Normal file
3
lib/javascripts/locale/vi.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.vi = function ( n ) {
|
||||
return "other";
|
||||
};
|
3
lib/javascripts/locale/zh.js
Normal file
3
lib/javascripts/locale/zh.js
Normal file
@ -0,0 +1,3 @@
|
||||
MessageFormat.locale.zh = function ( n ) {
|
||||
return "other";
|
||||
};
|
1593
lib/javascripts/messageformat.js
Normal file
1593
lib/javascripts/messageformat.js
Normal file
File diff suppressed because it is too large
Load Diff
74
lib/js_locale_helper.rb
Normal file
74
lib/js_locale_helper.rb
Normal file
@ -0,0 +1,74 @@
|
||||
module JsLocaleHelper
|
||||
|
||||
def self.output_locale(locale, translations = nil)
|
||||
|
||||
locale_str = locale.to_s
|
||||
|
||||
translations ||= YAML::load(File.open("#{Rails.root}/config/locales/client.#{locale_str}.yml"))
|
||||
|
||||
# We used to split the admin versus the client side, but it's much simpler to just
|
||||
# include both for now due to the small size of the admin section.
|
||||
#
|
||||
# For now, let's leave it split out in the translation file in case we want to split
|
||||
# it again later, so we'll merge the JSON ourselves.
|
||||
admin_contents = translations[locale_str].delete('admin_js')
|
||||
translations[locale_str]['js'].merge!(admin_contents) if admin_contents.present?
|
||||
message_formats = strip_out_message_formats!(translations[locale_str]['js'])
|
||||
|
||||
result = generate_message_format(message_formats, locale_str)
|
||||
|
||||
result << "I18n.translations = #{translations.to_json};\n"
|
||||
result << "I18n.locale = '#{locale_str}'\n"
|
||||
result
|
||||
end
|
||||
|
||||
def self.generate_message_format(message_formats, locale_str)
|
||||
formats = message_formats.map{|k,v| k.inspect << " : " << compile_message_format(locale_str ,v)}.join(" , ")
|
||||
|
||||
result = "MessageFormat = {locale: {}};\n"
|
||||
result << File.read(Rails.root + "lib/javascripts/locale/#{locale_str}.js") << "\n"
|
||||
|
||||
result << "I18n.messageFormat = (function(formats){
|
||||
var f = formats;
|
||||
return function(key, options) {
|
||||
var fn = f[key];
|
||||
if(fn){
|
||||
try {
|
||||
return fn(options);
|
||||
} catch(err) {
|
||||
return err.message;
|
||||
}
|
||||
} else {
|
||||
return 'Missing Key: ' + key
|
||||
}
|
||||
return f[key](options);
|
||||
};
|
||||
})({#{formats}});"
|
||||
end
|
||||
|
||||
def self.compile_message_format(locale, format)
|
||||
ctx = V8::Context.new
|
||||
ctx.load(Rails.root + 'lib/javascripts/messageformat.js')
|
||||
ctx.eval("mf = new MessageFormat('#{locale}');")
|
||||
ctx.eval("mf.precompile(mf.parse(#{format.inspect}))")
|
||||
|
||||
rescue V8::Error => e
|
||||
message = "Invalid Format: " << e.message
|
||||
"function(){ return #{message.inspect};}"
|
||||
end
|
||||
|
||||
def self.strip_out_message_formats!(hash, prefix = "", rval = {})
|
||||
if Hash === hash
|
||||
hash.each do |k,v|
|
||||
if Hash === v
|
||||
rval.merge!(strip_out_message_formats!(v, prefix + (prefix.length > 0 ? "." : "") << k, rval))
|
||||
elsif k.end_with?("_MF")
|
||||
rval[prefix + (prefix.length > 0 ? "." : "") << k] = v
|
||||
hash.delete(k)
|
||||
end
|
||||
end
|
||||
end
|
||||
rval
|
||||
end
|
||||
|
||||
end
|
82
spec/components/js_locale_helper_spec.rb
Normal file
82
spec/components/js_locale_helper_spec.rb
Normal file
@ -0,0 +1,82 @@
|
||||
require 'spec_helper'
|
||||
require_dependency 'js_locale_helper'
|
||||
|
||||
describe JsLocaleHelper do
|
||||
it 'should be able to generate translations' do
|
||||
JsLocaleHelper.output_locale('en').length.should > 0
|
||||
end
|
||||
|
||||
def setup_message_format(format)
|
||||
@ctx = V8::Context.new
|
||||
@ctx.eval('MessageFormat = {locale: {}};')
|
||||
@ctx.load(Rails.root + 'lib/javascripts/locale/en.js')
|
||||
compiled = JsLocaleHelper.compile_message_format('en', format)
|
||||
@ctx.eval("var test = #{compiled}")
|
||||
end
|
||||
|
||||
def localize(opts)
|
||||
@ctx.eval("test(#{opts.to_json})")
|
||||
end
|
||||
|
||||
it 'handles plurals' do
|
||||
setup_message_format('{NUM_RESULTS, plural,
|
||||
one {1 result}
|
||||
other {# results}
|
||||
}')
|
||||
localize(NUM_RESULTS: 1).should == '1 result'
|
||||
localize(NUM_RESULTS: 2).should == '2 results'
|
||||
end
|
||||
|
||||
it 'handles double plurals' do
|
||||
setup_message_format('{NUM_RESULTS, plural,
|
||||
one {1 result}
|
||||
other {# results}
|
||||
} and {NUM_APPLES, plural,
|
||||
one {1 apple}
|
||||
other {# apples}
|
||||
}')
|
||||
|
||||
|
||||
localize(NUM_RESULTS: 1, NUM_APPLES: 2).should == '1 result and 2 apples'
|
||||
localize(NUM_RESULTS: 2, NUM_APPLES: 1).should == '2 results and 1 apple'
|
||||
end
|
||||
|
||||
it 'handles select' do
|
||||
setup_message_format('{GENDER, select, male {He} female {She} other {They}} read a book')
|
||||
localize(GENDER: 'male').should == 'He read a book'
|
||||
localize(GENDER: 'female').should == 'She read a book'
|
||||
localize(GENDER: 'none').should == 'They read a book'
|
||||
end
|
||||
|
||||
it 'can strip out message formats' do
|
||||
hash = {"a" => "b", "c" => { "d" => {"f_MF" => "bob"} }}
|
||||
JsLocaleHelper.strip_out_message_formats!(hash).should == {"c.d.f_MF" => "bob"}
|
||||
hash["c"]["d"].should == {}
|
||||
end
|
||||
|
||||
it 'handles message format special keys' do
|
||||
ctx = V8::Context.new
|
||||
ctx.eval("I18n = {};")
|
||||
ctx.eval(JsLocaleHelper.output_locale('en',
|
||||
{
|
||||
"en" =>
|
||||
{
|
||||
"js" => {
|
||||
"hello" => "world",
|
||||
"test_MF" => "{HELLO} {COUNT, plural, one {1 duck} other {# ducks}}",
|
||||
"error_MF" => "{{BLA}",
|
||||
"simple_MF" => "{COUNT, plural, one {1} other {#}}"
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
ctx.eval('I18n.translations')["en"]["js"]["hello"].should == "world"
|
||||
ctx.eval('I18n.translations')["en"]["js"]["test_MF"].should be_nil
|
||||
|
||||
ctx.eval('I18n.messageFormat("test_MF", { HELLO: "hi", COUNT: 3 })').should == "hi 3 ducks"
|
||||
ctx.eval('I18n.messageFormat("error_MF", { HELLO: "hi", COUNT: 3 })').should =~ /Invalid Format/
|
||||
ctx.eval('I18n.messageFormat("missing", {})').should =~ /missing/
|
||||
ctx.eval('I18n.messageFormat("simple_MF", {})').should =~ /COUNT/ # error
|
||||
end
|
||||
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user