Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,28 @@ polyglot.t("car", 2);
=> "2 cars"
```

If you pass a `numberFormat` _function_ to the constructor, Polyglot will use
it to translate interpolated `Number`s to `String`s. That's useful because
different locales have different rules for formatting numbers: `2,000.56` in
English versus `1 234,56` in French, for instance.

```js
polyglot = new Polyglot({
phrases: { num_cars: '%{smart_count} car |||| %{smart_count} cars' },
numberFormat: new Intl.NumberFormat('en').format // Chrome, Firefox, IE11+, Node 0.12+ with ICU
})
polyglot.t("num_cars", 2000); // internally, calls options.numberFormat.format(2000)
=> "2,000 cars"
```

(A primer on [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat)
in Node: Node 0.12+ comes with Intl as long as it's compiled with ICU (which is
the default). By default, the only locale Node supports is en-US. You can add
[full-icu](https://www.npmjs.com/package/full-icu) to your project to support
other locales. Finally, Polyglot accepts a _function_, not an Intl.NumberFormat
instance: if you have a NumberFormat instance, pass its `.format` property to
Polyglot.

If you like, you can provide a default value in case the phrase is missing.
Use the special option key "_" to specify a default.

Expand Down
17 changes: 13 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ var tokenRegex = /%\{(.*?)\}/g;
//
// You should pass in a third argument, the locale, to specify the correct plural type.
// It defaults to `'en'` with 2 plural forms.
function transformPhrase(phrase, substitutions, locale) {
function transformPhrase(phrase, substitutions, locale, numberFormat) {
if (typeof phrase !== 'string') {
throw new TypeError('Polyglot.transformPhrase expects argument #1 to be string');
}
Expand All @@ -144,8 +144,14 @@ function transformPhrase(phrase, substitutions, locale) {
// Interpolate: Creates a `RegExp` object for each interpolation placeholder.
result = result.replace(tokenRegex, function (expression, argument) {
if (!has(options, argument)) { return ''; }

var replacement = options[argument];
if (typeof replacement === 'number') {
replacement = numberFormat(replacement);
}

// Ensure replacement value is escaped to prevent special $-prefixed regex replace tokens.
return replace.call(options[argument], dollarRegex, dollarBillsYall);
return replace.call(replacement, dollarRegex, dollarBillsYall);
});

return result;
Expand All @@ -157,6 +163,7 @@ function Polyglot(options) {
this.phrases = {};
this.extend(opts.phrases || {});
this.currentLocale = opts.locale || 'en';
this.numberFormat = opts.numberFormat || String;
this.allowMissing = !!opts.allowMissing;
this.warn = opts.warn || warn;
}
Expand All @@ -165,7 +172,9 @@ function Polyglot(options) {
//
// Get or set locale. Internally, Polyglot only uses locale for pluralization.
Polyglot.prototype.locale = function (newLocale) {
if (newLocale) this.currentLocale = newLocale;
if (newLocale) {
this.currentLocale = newLocale;
}
return this.currentLocale;
};

Expand Down Expand Up @@ -314,7 +323,7 @@ Polyglot.prototype.t = function (key, options) {
result = key;
}
if (typeof phrase === 'string') {
result = transformPhrase(phrase, opts, this.currentLocale);
result = transformPhrase(phrase, opts, this.currentLocale, this.numberFormat);
}
return result;
};
Expand Down
13 changes: 12 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ describe('t', function () {
hello: 'Hello',
hi_name_welcome_to_place: 'Hi, %{name}, welcome to %{place}!',
name_your_name_is_name: '%{name}, your name is %{name}!',
empty_string: ''
empty_string: '',
number: '%{number}'
};

var polyglot;
Expand Down Expand Up @@ -89,6 +90,16 @@ describe('t', function () {
expect(instance.t('nav.cta.join_now')).to.equal('Join now!');
expect(instance.t('header.sign_in')).to.equal('Sign In');
});

it('uses numberFormat', function () {
var instance = new Polyglot({
phrases: phrases,
// prove we're passed a Number by doing math on it and formatting it
numberFormat: function (n) { return 'x' + (n + 2); }
});

expect(instance.t('number', { number: 1234.56 })).to.equal('x1236.56');
});
});

describe('pluralize', function () {
Expand Down