UNPKG

11 kBMarkdownView Raw
1# ember-intl
2
3[![npm Version][npm-badge]][npm]
4[![Build Status][travis-badge]][travis]
5[![npm](https://img.shields.io/npm/dm/ember-intl.svg)](https://www.npmjs.com/package/ember-intl)
6[![Ember Observer Score](http://emberobserver.com/badges/ember-intl.svg)](http://emberobserver.com/addons/ember-intl)
7
8## Notable Features
9
10* 💵 Locale-aware numbers. Formatting of currencies, decimals, and percentages.
11* 📅 Locale-aware dates and times formatting
12* 🕑 Locale-aware display of relative time. I.e, `"now"`, `"yesterday"`, `"2 mo. ago"`
13* 💬 ICU Message Syntax. Pluralization and formatted segments (numbers, datetime, etc.).
14* 🌐 Support for 150+ languages.
15* 📜 Built largely on standards. [ICU message syntax][ICU] & [Native Intl API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl).
16* ⚡ Extensive Ember Service API and template helpers for formatting and translating.
17* 🎉 [Advanced addon support](https://ember-intl.github.io/ember-intl/docs/advanced/addon-support) to provide translations to the host app
18
19## Installation
20
21`ember i ember-intl`
22
23## Documentation
24
25[4.x (current stable)](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs)
26[3.x](https://github.com/ember-intl/ember-intl/tree/3.x/docs)
27[2.x](https://github.com/ember-intl/ember-intl/tree/2.x/docs)
28
29## Migrating from 2.0?
30
31[Here is a light touch migration guide to help you get started](https://ember-intl.github.io/ember-intl/docs/legacy/migration-2-0-to-3-0). If you uncover any gaps, submit a PR to update the migration doc or open an issue.
32
33## Translations
34Translations are defined in [ICU message syntax][ICU] and store in `<project_root>/translations` in either JSON and/or YAML format. Nested directories are supported along with nested objects within your translation files.
35
36Example basic translation file `/translations/homepage/en-us.yaml`:
37
38```yaml
39homepage:
40 banner: '<strong>{product}</strong> will cost <em>{price, number, USD}</em> if ordered by {deadline, date, time}'
41```
42
43## Setting Locale
44
45This can be done at any point after your app boots. This is typically done within your Application route's `beforeModel` hook by calling `intl.setLocale('en-us')` [Read more about the Service API](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs/guide/ember-service-api).
46
47```js
48 // app/routes/application.js
49 export default Route.extend({
50 intl: service(),
51 beforeModel() {
52 this._super(...arguments)
53 /* NOTE: if you lazily load translations, here is also where you would load them via `intl.addTranslations` */
54 return this.intl.setLocale(['fr-fr', 'en-us']); /* array optional */
55 }
56 });
57```
58
59## Helper Examples
60
61### Format Message
62
63Compiles a [ICU message syntax][ICU] strings with its hash values passed.
64
65```
66# en-us.yml
67photos:
68 banner: "You have {numPhotos, plural, =0 {no photos.} =1 {one photo.} other {# photos.}}"
69```
70
71**Template Helper**
72
73```hbs
74{{t 'photos.banner' numPhotos=model.photos.length}}
75```
76
77**Service API**
78
79```js
80export default Component.extend({
81 intl: service(),
82
83 banner: computed('intl.locale', 'model.photos.length', function() {
84 return this.intl.t('photos.banner', {
85 photos: this.get('model.photos.length')
86 });
87 })
88});
89```
90
91### Format Number
92Formats numbers using [`Intl.NumberFormat`][Intl-NF], and returns the formatted string value.
93
94```hbs
95{{format-number num}}
96{{format-number num format='EUR'}}
97{{format-number num style='currency' currency='USD'}}
98```
99
100Or programmatically convert a number within any Ember Object.
101
102```js
103export default Component.extend({
104 intl: service(),
105 computedNumber: computed('intl.locale', 'cost', function() {
106 return this.intl.formatNumber(this.cost/*, optional options hash */);
107 })
108});
109```
110
111#### Format Number Options
112
113[List of supported format number options](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs/helpers/format-number#format-number-options)
114
115### Format Date
116
117Formats dates using [`Intl.DateTimeFormat`][Intl-DTF], and returns the formatted string value.
118
119```hbs
120{{format-date now weekday='long' timeZone='UTC'}}
121{{format-date now hour='numeric' minute='numeric' hour12=false}}
122```
123
124Or programmatically convert a date within any Ember Object.
125
126```js
127export default Component.extend({
128 intl: service(),
129 computedNow: computed('intl.locale', function() {
130 return this.intl.formatDate(new Date()/*, optional options hash */);
131 })
132});
133```
134
135#### Format Date Options
136
137[List of supported format date options](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs/helpers/format-date#format-date-time-options)
138
139### Format Time
140
141This is just like the `{{format-date}}` helper, except it will reference any string-named `format` from [`formats.time`](#dataintlformats).
142
143```hbs
144{{format-time now format='hhmmss'}}
145{{format-time now hour='numeric' minute='numeric' hour12=false}}
146```
147
148Or programmatically convert a time within any Ember Object.
149
150```js
151// example
152export default Component.extend({
153 intl: service(),
154 computedNow: computed('intl.locale', function() {
155 return this.intl.formatTime(new Date()/*, optional options hash */);
156 })
157});
158```
159
160#### Format Time Options
161[List of supported format date options](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs/helpers/format-date#format-date-time-options)
162
163### Format Relative
164
165Formats dates relative to "now" using [`IntlRelativeFormat`][Intl-RF], and returns the formatted string value.
166
167```js
168export default Component.extend({
169 timestamp: computed(function() {
170 let date = new Date();
171 date.setDate(date.getDate() - 3);
172 return date;
173 })
174});
175```
176
177```hbs
178{{format-relative timestamp}} -> 3 days ago
179```
180
181```hbs
182{{format-relative timestamp units='day'}} -> 3 days ago
183```
184
185`units` is optional, by default will default to `best-fit`. [A full list of supported unit options](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs/helpers/format-relative#format-relative-options)
186
187Or programmatically convert a relative time within any Ember Object.
188
189```js
190export default Component.extend({
191 intl: service(),
192 yesterday: computed('intl.locale', function() {
193 let date = new Date();
194 return this.intl.formatRelative(date.setDate(date.getDate() - 1)/*, optional options hash */);
195 })
196});
197```
198
199#### Live Relative Timestamp
200
201Recompute the relative timestamp on an interval by passing an `interval` argument (in milliseconds).
202
203```hbs
204{{format-relative now interval=1000}} -> now, 1 second ago, 2 seconds ago, etc. (will recompute every 1s)
205```
206
207#### Format Relative Options
208
209[List of supported format relative options](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs/helpers/format-relative#format-relative-options)
210
211#### Formatting a string literal ICU messages
212
213**Template Helper**
214
215```hbs
216{{format-message "{name} took {numPhotos, plural, =0 {no photos} =1 {one photo} other {# photos}} on {timestamp, date, long}"
217 name=user.username
218 numPhotos=num
219 timestamp=yesterday
220}}
221```
222
223**Service API**
224
225```js
226export default Component.extend({
227 intl: service(),
228 count: 0,
229 label: computed('intl.locale', 'model.photos.length', function() {
230 return this.intl.formatMessage(`
231 You took {numPhotos, plural,
232 =0 {no photos}
233 =1 {one photo}
234 other {# photos}
235 }
236 `,
237 {
238 numPhotos: this.get('model.photos.length')
239 });
240 }).readOnly()
241});
242```
243
244### Format HTML Message
245
246Escapes all hash arguments and returns as an htmlSafe String which renders an ElementNode. To enable rendering HTML within translations, pass an `htmlSafe` attribute to the `t` helper.
247
248```hbs
249{{t 'a.translation' htmlSafe=true}}
250{{format-message '<em>{photos, number}</em>' photos=models.photos.length htmlSafe=true}}
251```
252
253## Named Formats
254
255Specifying format options (e.g.: style="currency" currency="USD") in every use of format helper can become a problem in large code bases, and isn't DRY. Instead, you can provide named formats through the use of exporting a POJO from `app/formats`. All helpers accept a `format` property which accepts a key that maps to the format option under its respected type (time, date, number, relative).
256
257For example:
258
259
260```js
261// app/formats.js
262export default {
263 date: {
264 hhmmss: {
265 hour: 'numeric',
266 minute: 'numeric',
267 second: 'numeric'
268 }
269 }
270};
271```
272
273```hbs
274{{format-date 'Thu Jan 23 2014 13:00:44' format='hhmmss'}}
275```
276
277```js
278this.intl.formatDate('Thu Jan 23 2014 13:00:44', {
279 format: 'hhmmss'
280})
281```
282
283Output of both the helper and the programmatic example:
284
285> 1:00:44 PM
286
287## Helper Options
288
289* All helpers accept optional arguments:
290 * `locale` argument to explicitly pass/override the application locale
291 * `format` argument which you pass in a key corresponding to a format configuration in `app/formats.js`
292
293## Asynchronously loading translations
294
295Asynchronously loading translations instead of bundling translations within `app.js` are fully-supported as of 2.x.
296https://ember-intl.github.io/ember-intl/docs/guide/asynchronously-loading-translations
297
298## Testing with ember-intl
299
300ember-intl ships with a number of helpers for assist with writing tests. [Documentation](https://ember-intl.github.io/ember-intl/versions/v4.0.0/docs/guide/testing)
301
302
303## Common Errors
304
305> `date value is not finite in DateTimeFormat.format()`
306
307Browser vendors implement date/time parsing differently. For example, the following will parse correctly in Chrome but fail in Firefox: `new Intl.DateTimeFormat().format('2015-04-21 20:47:31 GMT');`
308
309The solution is the ensure that the value you are passing in is in a format which is valid for the `Date` constructor. This library currently does not try and normalize date strings outside of what the browser already implements.
310
311## Migrating from ember-i18n
312
313* Simple migration tool to convert your translations files and application code to this addon. Feel free to report any issues with the migration tool [here](https://github.com/DockYard/ember-i18n-to-intl-migrator/issues).
314- https://github.com/DockYard/ember-i18n-to-intl-migrator
315
316[npm]: https://www.npmjs.org/package/ember-intl
317[npm-badge]: https://img.shields.io/npm/v/ember-intl.svg?style=flat-square
318[travis]: https://travis-ci.org/ember-intl/ember-intl
319[travis-badge]: https://travis-ci.org/ember-intl/ember-intl.svg?branch=master
320[Intl-RF]: https://github.com/yahoo/intl-relativeformat
321[Intl-MF]: https://github.com/yahoo/intl-messageformat
322[Intl]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
323[Intl-NF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
324[Intl-DTF]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
325[ICU]: https://formatjs.io/guides/message-syntax/
326[CLDR]: http://cldr.unicode.org/
327[Intl.js]: https://github.com/andyearnshaw/Intl.js
328[LICENSE]: https://github.com/yahoo/yahoo-intl/blob/master/LICENSE
329[FormatJS]: http://formatjs.io/