Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added support for {{ mustache }} in message strings

  • Loading branch information...
commit 8fed09279b315c74bf05559b9066f88dd7f7fa76 1 parent 9a6347c
@matthias matthias authored
View
16 README.md
@@ -113,14 +113,18 @@ Translates a single phrase and adds it to locales if unknown. Returns translated
// template and global (this.locale == 'de')
__('Hello'); // Hallo
__('Hello %s', 'Marcus'); // Hallo Marcus
+ __('Hello {{name}}', { name: 'Marcus' }); // Hallo Marcus
+
// scoped via req object (req.locale == 'de')
req.__('Hello'); // Hallo
req.__('Hello %s', 'Marcus'); // Hallo Marcus
+ req.__('Hello {{name}}', { name: 'Marcus' }); // Hallo Marcus
// passing specific locale
__({phrase: 'Hello', locale: 'fr'}); // Salut
__({phrase: 'Hello %s', locale: 'fr'}, 'Marcus'); // Salut Marcus
+ __({phrase: 'Hello {{name}}, locale: 'fr'}, { name: 'Marcus' }); // Salut Marcus
### __n()
@@ -219,6 +223,18 @@ this puts *Hello Marcus, how are you today?*. You might add endless arguments an
which puts *Hello Marcus, how are you today? How was your weekend.*
+### mustache support
+
+You may also use [mustach](http://mustache.github.io/) syntax for your message strings. To pass named parameters to your message, just provide an object as the second parameter. You can still pass unnamed parameters by adding additional arguments.
+
+ var greeting = __('Hello {{name}}, how are you today?', { name: 'Marcus' });
+
+this puts *Hello Marcus, how are you today?*. You might also combine it with sprintf arguments and also nest it.
+
+ var greeting = __('Hello {{name}}, how was your %s.', { name: 'Marcus' }, __('weekend'));
+
+which puts *Hello Marcus, how was your weekend.*
+
### variable support
you might even use dynamic variables as they get interpreted on the fly. Better make sure no user input finds it's way to that point as they all get added to the `en.js` file if not yet existing.
View
2  TODO.md
@@ -3,5 +3,5 @@ Roadmap
* better parsing of defaults (and adding more reasonable default settings)
* lot's of more configure settings
* better sanitation in all fs operations => plugin system for storage
-* named parameters in translation strings
+* ~named parameters in translation strings~
* api docs
View
17 i18n.js
@@ -14,6 +14,7 @@ var vsprintf = require('sprintf').vsprintf,
debug = require('debug')('i18n:debug'),
warn = require('debug')('i18n:warn'),
error = require('debug')('i18n:error'),
+ Mustache = require('mustache'),
locales = {},
api = ['__', '__n', 'getLocale', 'setLocale', 'getCatalog'],
pathsep = path.sep || '/', // ---> means win support will be available in node 0.8.x and above
@@ -98,7 +99,12 @@ i18n.__ = function i18nTranslate(phrase) {
// if we have extra arguments with strings to get replaced,
// an additional substition injects those strings afterwards
- if (arguments.length > 1) {
+ if (arguments[1] !== null && typeof arguments[1] === "object") {
+ msg = Mustache.render(msg, arguments[1]);
+ if (arguments.length > 2) {
+ msg = vsprintf(msg, Array.prototype.slice.call(arguments, 2));
+ }
+ } else if (arguments.length > 1) {
msg = vsprintf(msg, Array.prototype.slice.call(arguments, 1));
}
return msg;
@@ -137,9 +143,14 @@ i18n.__n = function i18nTranslatePlural(singular, plural, count) {
// if we have extra arguments with strings to get replaced,
// an additional substition injects those strings afterwards
- if (arguments.length > 3) {
+ if (arguments[3] !== null && typeof arguments[3] === "object") {
+ msg = Mustache.render(msg, arguments[3]);
+ if (arguments.length > 4) {
+ msg = vsprintf(msg, Array.prototype.slice.call(arguments, 2));
+ }
+ } else if (arguments.length > 3) {
msg = vsprintf(msg, Array.prototype.slice.call(arguments, 3));
- }
+ }
return msg;
};
View
4 locales/de.js
@@ -18,5 +18,7 @@
"one": "There is one monkey in the %s",
"other": "There are %d monkeys in the %s"
},
- "Hello %s": "Hallo %s"
+ "Hello %s": "Hallo %s",
+ "Hello {{name}}": "Hallo {{name}}",
+ "Hello {{name}}, how was your %s?": "Hallo {{name}}, wie war dein %s?"
}
View
4 locales/en.js
@@ -18,5 +18,7 @@
"one": "There is one monkey in the %s",
"other": "There are %d monkeys in the %s"
},
- "Hello %s": "Hello %s"
+ "Hello %s": "Hello %s",
+ "Hello {{name}}": "Hello {{name}}",
+ "Hello {{name}}, how was your %s?": "Hello {{name}}, how was your %s?"
}
View
1  package.json
@@ -15,6 +15,7 @@
},
"dependencies": {
"sprintf": ">=0.1.1",
+ "mustache": "*",
"debug": "*"
},
"devDependencies": {
View
16 test/i18n.api.js
@@ -95,6 +95,12 @@ describe('Module API', function () {
should.equal(__('Hello %s, how are you today? How was your %s.', 'Marcus', __('weekend')), 'Hello Marcus, how are you today? How was your weekend.');
});
+ it('should return en translations as expected, using mustached messages', function () {
+ i18n.setLocale('en');
+ should.equal(__('Hello {{name}}', { name: 'Marcus' }), 'Hello Marcus');
+ should.equal(__('Hello {{name}}, how was your %s?', { name: 'Marcus' }, __('weekend')), 'Hello Marcus, how was your weekend?');
+ });
+
it('should return de translations as expected', function () {
i18n.setLocale('de');
should.equal(__('Hello'), 'Hallo');
@@ -102,6 +108,12 @@ describe('Module API', function () {
should.equal(__('Hello %s, how are you today? How was your %s.', 'Marcus', __('weekend')), 'Hallo Marcus, wie geht es dir heute? Wie war dein Wochenende.');
});
+ it('should return de translations as expected, using mustached messages', function () {
+ i18n.setLocale('de');
+ should.equal(__('Hello {{name}}', { name: 'Marcus' }), 'Hallo Marcus');
+ should.equal(__('Hello {{name}}, how was your %s?', { name: 'Marcus' }, __('weekend')), 'Hallo Marcus, wie war dein Wochenende?');
+ });
+
it('should also return translations when iterating thru variables values', function () {
var i = 0,
greetings = ['Hi', 'Hello', 'Howdy'],
@@ -138,10 +150,12 @@ describe('Module API', function () {
// passing specific locale
should.equal(__({phrase: 'Hello', locale: 'de'}), 'Hallo');
- should.equal(__({phrase: 'Hello %s', locale: 'de'}, 'Marcus'), 'Hallo Marcus');
+ should.equal(__({phrase: 'Hello %s', locale: 'de'}, 'Marcus'), 'Hallo Marcus');
+ should.equal(__({phrase: 'Hello {{name}}', locale: 'de'}, { name: 'Marcus' }), 'Hallo Marcus');
should.equal(__({phrase: 'Hello', locale: 'en'}), 'Hello');
should.equal(__({phrase: 'Hello %s', locale: 'en'}, 'Marcus'), 'Hello Marcus');
+ should.equal(__({phrase: 'Hello {{name}}', locale: 'en'}, { name: 'Marcus' }), 'Hello Marcus');
i18n.setLocale('de');
should.equal(__('Hello'), 'Hallo');
Please sign in to comment.
Something went wrong with that request. Please try again.