This library provides Ember Handlebar helpers and a localization service injected into views, routes, models, controllers, and components. The service, and helpers, provide a way to format dates, numbers, strings messages, including pluralization.
Ember Intl is part of FormatJS, the docs can be found on the website:
- Ember-cli >= 0.1.5
- Ember >= 1.10.x
- HTMLBars
npm install --save ember-intl
ember g ember-intl
ember g locale en
- If you are targeting a browser that doesn't support the native Intl API, you need to load the shim. The Intl.JS polyfill is automatically added into your asset distribution folder, so you need to add the following to your index.html:
<script src="/assets/intl/polyfill/Intl.complete.js"></script>
- Add custom messages per locale in their respective ES6 locale module. Example of app/locales/en.js:
import Locale from 'ember-intl/models/locale';
export default Locale.extend({
messages: {
product: {
info: '{product} will cost {price, number, EUR} if ordered by {deadline, date, time}',
html: {
info: '<strong>{product}</strong> will cost <em>{price, number, EUR}</em> if ordered by {deadline, date, time}'
}
}
}
});
- Configure which locale you want to use at runtime:
- Open app/app.js
- Add a
ready
hook:
var App = Ember.Application.extend({
ready: function () {
// read more: http://formatjs.io/guide/#client-side
var language = navigator.language || navigator.browserLanguage;
this.intl.set('locales', [language, 'en']);
}
});
Formats numbers using Intl.NumberFormat
, and returns the formatted string value.
Formats dates using Intl.DateTimeFormat
, and returns the formatted string value.
This is just like the {{format-date}}
helper, except it will reference any string-named format
from formats.time
.
Formats dates relative to "now" using IntlRelativeFormat
, and returns the formatted string value.
Formats ICU Message strings with the given values supplied as the hash arguments.
You have {numPhotos, plural,
=0 {no photos.}
=1 {one photo.}
other {# photos.}}
This delegates to the {{format-message}}
helper, but will first HTML-escape all of the hash argument values. This allows the message
string to contain HTML and it will be considered safe since it's part of the template and not user-supplied data.
Utility helper for accessing and returning the value the properties from the locale's message object via a string namespace.
Will return the message from the current locale, or locale explicitly passed as an argument, message object.
// app/locales/en.js
import Locale from 'ember-intl/models/locale';
export default Locale.extend({
messages: {
product: {
info: '{product} will cost {price, number, EUR} if ordered by {deadline, date, time}'
}
}
});
- All helpers accept optional arguments:
locales
argument to explicitly pass/override the application localeformat
argument which you pass in a key corresponding to a format configuration inapp/formats.js
If using the intl helpers within a components or views that is unit tested, needs
the service, helper, and formatter into the unit test.
In the setup hook of moduleFor
/moduleForComponent
you'll want to also invoke registerIntl(container);
-- which is a utility function to setup the injection logic on the unit test container.
NOTE: Add the following above all script tags in tests/index.html
<script src="assets/intl/polyfill/Intl.complete.js"></script>
This is to shim your test runner if running within phantomjs, or any browser which does not natiely support the Intl API.
/**
* unit test for testing index view which contains the helpers: `format-message` and `intl-get`
*
* unit/views/index-test.js
*/
import Ember from 'ember';
import { registerIntl } from '../../../initializers/ember-intl';
import {
moduleFor,
test
} from 'ember-qunit';
moduleFor('view:index', 'IndexView', {
needs: [
'template:index',
'service:intl',
'helper:intl-get',
'formatter:format-message',
'locale:en',
'locale:es'
],
setup: function () {
// depending on your test library, container will be hanging off `this`
// or otherwise passed in as the first argument
var container = this.container || arguments[0];
// injects the service on to all logical factory types
registerIntl(container);
// set the initial intl service locale to `en-us`
var intl = container.lookup('service:intl');
intl.set('locales', 'en-us');
}
});
test('index renders', function () {
expect(2);
var view = this.subject({
context: Ember.Object.create({
firstName: 'Tom'
})
});
var intl = view.get('intl');
// render view
Ember.run(view, 'appendTo', '#qunit-fixture');
equal(view.$().text().trim(), "hello Tom");
Ember.run(function () {
intl.set('locales', 'es');
});
equal(view.$().text().trim(), "hola Tom");
// destroy view
Ember.run(view, 'destroy');
});
ember server
- Visit your app at http://localhost:4200.
ember test
ember test --server