UNPKG

16.4 kBMarkdownView Raw
1# ![format-message][logo]
2
3> Internationalize text, numbers, and dates using ICU Message Format
4
5[![npm Version][npm-image]][npm]
6[![Build Status][build-image]][build]
7[![JS Standard Style][style-image]][style]
8[![MIT License][license-image]][LICENSE]
9
10
11Quick Examples
12--------------
13
14`npm install format-message --save`
15
16By default, the passed in string is parsed and formatted.
17
18```js
19var formatMessage = require('format-message')
20var message = formatMessage('Hello { place }!', { place: 'World' })
21```
22
23You can pass an object to provide more information about a message.
24
25```js
26import formatMessage from 'format-message'
27
28let message = formatMessage({
29 id: 'welcome_name', // optional, can be generated from `default`
30 default: 'Welcome, {name}!',
31 // optional description gives translators more context
32 description: 'Greeting at the top of the home page, showing the current user’s preferred name'
33}, {
34 name: user.preferredName
35})
36```
37
38Configure format-message to use translations, infer missing ids from the default message, report and replace missing translations, and add custom placeholder style formats.
39
40```js
41formatMessage.setup({
42 locale: 'es-ES', // what locale strings should be displayed
43 translations: require('./locales'), // object containing translations
44 generateId: require('format-message-generate-id/underscored_crc32'), // function to generate a missing id from the default message
45 missingReplacement: '!!NOT TRANSLATED!!', // use this when a translation is missing instead of the default message
46 missingTranslation: 'ignore', // don't console.warn or throw an error when a translation is missing
47 formats: {
48 number: { // add '{ amount, number, EUR }' format
49 EUR: { style: 'currency', currency: 'EUR' }
50 },
51 date: { // add '{ day, date, weekday }' format
52 weekday: { weekday: 'long' }
53 }
54 }
55})
56```
57
58Formatting `number`, `date`, and `time` arguments relies on the ECMAScript Internationalization API (`Intl`). If you are in an environment missing this API ([like node <= 0.12, IE < 11, or Safari < 10][caniuse-intl]) you'll want to use a [polyfill][intl]. Otherwise an error will be thrown when trying to format these arguments.
59
60
61Format Overview
62---------------
63
64The [ICU Message Format][icu-message] is a great format for user-visible strings, and includes simple placeholders, number and date placeholders, and selecting among submessages for gender and plural arguments. The format is used in apis in [C++][icu-cpp], [PHP][icu-php], and [Java][icu-java]. There is a [guide for translators][icu-for-translators] you can send to your translators, and it's a nice primer for developers as well.
65
66`format-message` provides a way to write your default (often English) message patterns as literals in your source, and then lookup translations at runtime. There are also tools to lint, extract, and inline translations.
67
68This relies on [message-format][message-format] for parsing and formatting ICU messages.
69
70### Supported ICU Formats
71
72See [message-format][message-format] for supported ICU formats.
73
74### Quoting escaping rules
75
76See the [ICU site][icu-message] and [message-format][message-format] for details on how to escape special characters in your messages.
77
78### Loading locale data
79
80`format-message` supports plurals for all CLDR languages. Locale-aware formatting of number, date, and time are delegated to the `Intl` apis, and select is the same across all locales. You don't need to load any extra files for particular locales for `format-message` itself.
81
82
83API
84---
85
86### `formatMessage(pattern[, args[, locales]])`
87
88Translate and format the message with the given pattern and arguments. Literal arguments for `pattern` and `locales` are recommended so you can take advantage of linting, extraction, and inlining tools.
89
90Parameters
91
92- `pattern` is a string or object describing the message. A string value is equivalent to `{ default: value }`.
93 - `default` is a properly formatted ICU Message Format pattern. A poorly formatted pattern will cause an `Error` to be thrown.
94 - This will be used directly if no translations are conifgured or if the translation is missing and no `missingReplacement` is configured.
95 - This is also used to generate an inferred `id`, if none is explicitly included.
96 - `id` is a string identifier for the message. This is used as a key to look up the translation from the configured `translations`. If none is specified, one is generated from the `default` pattern.
97 - `description` is a string providing additional context for this message. This has no runtime effect, but can be extracted along with the default message to be sent to translators.
98- `args` is an object containing the values to replace placeholders with. Required if the pattern contains placeholders.
99- `locales` is an optional string with a BCP 47 language tag, or an array of such strings.
100 - When specified, format-message will attempt to look up the translation for each language until one is found.
101 - When ommitted the locale configured in `setup()` is used instead.
102
103### `formatMessage.setup(options)`
104
105Configure `formatMessage` behavior for subsequent calls. This should be called before any code that uses `formatMessage`. Returns an object containing the current options.
106
107Parameters
108
109- `options` is an object containing the following config values:
110 - `locale` is the default locale to use when no locale is passed to `formatMessage`. Defaults to `"en"`.
111 - `translations` is an object with locales as properties, each value is an object with message ids as properties. The value for each message id property is either the translated message pattern string, or an object with the `message` property containing the translated message pattern string.
112 - `generateId(defaultPattern)` is a function to generate an id from the default message pattern.
113 - `defaultPattern` is the default message pattern.
114 - This function must return a string id.
115 - The [`format-message-generate-id`][format-message-generate-id] module has a few functions you can use if you don't want to use your own.
116 - `missingReplacement` is a string or function that returns a string that will be used when a message translation isn't found. If a function, it will be called with `(pattern, id, locale)` parameters to get the replacement. If null or not specified, then the default message is used.
117 - `missingTranslation` is one of `"ignore"`, `"warning"`, `"error"`. By default it is `"warning"`, and missing translations cause a console warning. If `"error"`, an error is thrown.
118 - `formats` is an object containing objects that define placeholder styles `{ name, type, style }`:
119 - `number` is an object containing number format styles to add. Each property name can be used afterwards as a style name for a number placeholder. The value of each property is an object that will be passed to an [`Intl.NumberFormat`][mdn-intl-numberformat] constructor as the second argument.
120 - `date` is an object containing date format styles to add. Each property name can be used afterwards as a style name for a date placeholder. The value of each property is an object that will be passed to an [`Intl.DateTimeFormat`][mdn-intl-datetimeformat] constructor as the second argument.
121 - `time` is an object containing time format styles to add. Each property name can be used afterwards as a style name for a time placeholder. The value of each property is an object that will be passed to an [`Intl.DateTimeFormat`][mdn-intl-datetimeformat] constructor as the second argument.
122
123### `formatMessage.namespace()`
124
125Return a new instance of `formatMessage` with isolated configuration. Calls to `setup()`
126on the new namespace will not be affect any another namespace (including the global
127namespace).
128
129```js
130var namespace = formatMessage.namespace()
131
132formatMessage.setup({
133 locale: "en",
134 translations: {
135 en: {
136 foo: "foo"
137 }
138 }
139})
140
141namespace.setup({
142 locale: "fr",
143 transations: {
144 fr: {
145 foo: "bar"
146 }
147 }
148})
149
150formatMessage("foo") // => "foo"
151namespace("foo") // => "bar"
152```
153
154If you are using a custom namespace and still want to be able to extract strings
155using the format message CLI, create a module named `format-message.js` that exports
156the new namespace. Import formatMessage from this module in all other modules that
157use the namespace.
158
159### Localization apis
160
161format-message also provides a few extra functions to simplify localizing (but not translating) data. These mostly just pass through to `Intl` APIs.
162
163```js
164import { number, date, time, select, plural, selectordinal } from 'format-message'
165// or
166var { number, date, time, select, plural, selectordinal } = require('format-message')
167```
168
169### `number(value [, style [, locale ]])`
170
171Convert a number to a localized string.
172
173Parameters
174
175- `value` is the number to format.
176- `style` is the optional string name of a style (decimal, integer, percent, etc). Defaults to `'decimal'`.
177- `locale` is the optional BCP 47 language tag. If not passed, the locale passed to `setup()` will be used.
178
179### `date(value [, style [, locale ]])`
180
181Convert a date to a localized date string.
182
183Parameters
184
185- `value` is the date to format.
186- `style` is the optional string name of a style (short, medium, long, full, etc). Defaults to `'medium'`.
187- `locale` is the optional BCP 47 language tag. If not passed, the locale passed to `setup()` will be used.
188
189### `time(value [, style [, locale ]])`
190
191Convert a date to a localized time string.
192
193Parameters
194
195- `value` is the date to format.
196- `style` is the optional string name of a style (short, medium, long, full, etc). Defaults to `'medium'`.
197- `locale` is the optional BCP 47 language tag. If not passed, the locale passed to `setup()` will be used.
198
199### `select(value, options)`
200
201Select an option by exact text match. (This is not locale-specific.)
202
203Parameters
204
205- `value` is the string to match.
206- `options` is an object whose keys are candidates for matching `value`. The value of the property with the matching key is returned, or the `other` property's value. The object should always have an `other` property.
207
208### `plural(value [, offset ], options [, locale ])` and `selectordinal(value [, offset ], options [, locale ])`
209
210Select an option by matching plural rules. `plural` matches rules for cardinal numbers, and `selectordinal` matches rules for ordinal numbers. These function very similar to the parameters `plural` and `selectordinal` embedded in a message.
211
212Parameters
213
214- `value` is the number to match against plural rules.
215- `offset` is an optional number subtracted from value before matching keyword plural rules. The offset is not applied when matching exact number options.
216- `options` is an object whose keys are candidates for matching `value`. The value of the property with the matching key is returned, or the `other` property's value. The object should always have an `other` property. Keys should be either plural keywords (zero, one, two, few, many, other), or exact number matches (=13, =4, etc). Note that not all languages use all rules. For example English doesn't have a `zero` rule (0 falls under the `other` rule), but can still match `=0`.
217
218### format-message/react
219
220This module includes utilities for working specifically with react when composing messages with embedded components.
221
222### `formatChildren(message, elements)`
223
224Applies a message to a map of React elements to produce a list of child nodes.
225
226Parameters
227
228- `message` is a pre-formatted string containing tokens marking the beginning and ending of nodes.
229- `elements` is an object with keys matching tokens in the message, and values of React elements to put message parts in.
230
231Example
232
233```jsx
234import formatMessage from 'format-message'
235import {formatChildren} from 'format-message/react'
236
237export default ({ extensions }) =>
238 <div title={formatMessage('Choose a file')}>
239 {formatChildren(
240 formatMessage('Drag & Drop {extensions} files here <0>or</0> <1>Browse</1>', {
241 extensions
242 }),
243 [
244 <span className="or" />,
245 <span className="browse" />
246 ]
247 )}
248 </div>
249```
250
251produces the same tree as
252
253```jsx
254<div title="something">
255 Drag & Drop {extensions} files here
256 <span className="or">or</span>
257 <span className="browse">
258 Browse
259 </span>
260</div>
261```
262
263### format-message/inferno
264
265This module includes utilities for working specifically with Inferno when composing messages with embedded components. The API is identical to format-message/react, only it works with Inferno vdom nodes instead of React elements.
266
267### `formatChildren(message, elements)`
268
269Applies a message to a map of vdom nodes to produce a list of child nodes.
270
271Parameters
272
273- `message` is a pre-formatted string containing tokens marking the beginning and ending of nodes.
274- `elements` is an object with keys matching tokens in the message, and values of vdom elements to put message parts in.
275
276
277Example Messages
278----------------
279
280The examples provide sample output. Some assume you have configured with translations.
281
282### Simple messages with no placeholders
283
284```js
285formatMessage('My Collections')
286// "Minhas Coleções"
287```
288
289### Simple string placeholders
290
291```js
292formatMessage('Welcome, {name}!', { name: 'Bob' })
293// "Bem Vindo, Bob!"
294```
295
296### String placeholders with nested data
297
298```js
299formatMessage('Welcome, {people.wes.name}, {people.julie.name}, and {people.sharon.name}!', {
300 people: {
301 wes: {
302 name: 'Wes Phillips'
303 },
304 julie: {
305 name: 'Julie Roberts'
306 },
307 sharon: {
308 name: 'Sharon Sanders'
309 }
310 }
311})
312// "Welcome, Wes Phillips, Julie Roberts, and Sharon Sanders!"
313```
314
315### Complex number, date, and time placeholders
316
317```js
318formatMessage('{ n, number, percent }', { n: 0.1 })
319// or preferred since there is no text to translate:
320number(0.1, 'percent')
321// "10%"
322
323formatMessage('{ shorty, date, short }', { shorty: new Date() })
324// or preferred since there is no text to translate:
325date(new Date(), 'short')
326// "1/1/15"
327
328formatMessage('You took {n,number} pictures since {d,date} {d,time}', { n: 4000, d: new Date() })
329// "You took 4,000 pictures since Jan 1, 2015 9:33:04 AM"
330```
331
332### Complex string with select and plural in ES6
333
334```js
335import formatMessage from 'format-message'
336
337// using a template string for multiline, NOT for interpolation
338formatMessage(`On { date, date, short } {name} ate {
339 numBananas, plural,
340 =0 {no bananas}
341 =1 {a banana}
342 =2 {a pair of bananas}
343 other {# bananas}
344 } {
345 gender, select,
346 male {at his house.}
347 female {at her house.}
348 other {at their house.}
349 }`, {
350 date: new Date(),
351 name: 'Curious George',
352 gender: 'male',
353 numBananas: 27
354})
355// "On 1/1/15 Curious George ate 27 bananas at his house."
356```
357
358
359License
360-------
361
362This software is free to use under the MIT license. See the [LICENSE-MIT file][LICENSE] for license text and copyright information.
363
364
365[logo]: https://cdn.rawgit.com/format-message/format-message/2febdd8/logo.svg
366[npm]: https://www.npmjs.org/package/format-message
367[npm-image]: https://img.shields.io/npm/v/format-message.svg
368[build]: https://travis-ci.org/format-message/format-message
369[build-image]: https://img.shields.io/travis/format-message/format-message.svg
370[style]: https://github.com/feross/standard
371[style-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg
372[license-image]: https://img.shields.io/npm/l/format-message.svg
373[caniuse-intl]: http://caniuse.com/#feat=internationalization
374[icu-message]: http://userguide.icu-project.org/formatparse/messages
375[icu-cpp]: http://icu-project.org/apiref/icu4c/classicu_1_1MessageFormat.html
376[icu-php]: http://php.net/manual/en/class.messageformatter.php
377[icu-java]: http://icu-project.org/apiref/icu4j/
378[intl]: https://github.com/andyearnshaw/Intl.js
379[icu-for-translators]: http://format-message.github.io/icu-message-format-for-translators/
380[format-message-generate-id]: https://github.com/format-message/format-message/tree/master/packages/format-message-generate-id
381[message-format]: https://github.com/format-message/message-format
382[mdn-intl-datetimeformat]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
383[mdn-intl-numberformat]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
384[LICENSE]: https://github.com/format-message/format-message/blob/master/LICENSE-MIT