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 |
|
11 | Quick Examples
|
12 | --------------
|
13 |
|
14 | `npm install format-message --save`
|
15 |
|
16 | By default, the passed in string is parsed and formatted.
|
17 |
|
18 | ```js
|
19 | var formatMessage = require('format-message');
|
20 | var message = formatMessage('Hello { place }!', { place: 'World' });
|
21 | ```
|
22 |
|
23 | You can pass an object to provide more information about a message.
|
24 |
|
25 | ```js
|
26 | import formatMessage from 'format-message'
|
27 |
|
28 | let 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 |
|
38 | Configure 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
|
41 | formatMessage.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 |
|
58 | Formatting `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][caniuse-intl]) you'll want to use a [polyfill][intl]. Otherwise formatting falls back on `toLocaleString` methods, which are most likely just aliases for `toString`.
|
59 |
|
60 |
|
61 | Format Overview
|
62 | ---------------
|
63 |
|
64 | The [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 |
|
68 | This relies on [message-format][message-format] for parsing and formatting ICU messages.
|
69 |
|
70 | ### Supported ICU Formats
|
71 |
|
72 | See [message-format][message-format] for supported ICU formats.
|
73 |
|
74 | ### Quoting escaping rules
|
75 |
|
76 | See 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 |
|
83 | API
|
84 | ---
|
85 |
|
86 | ### `formatMessage(pattern[, args[, locales]])`
|
87 |
|
88 | Translate 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 |
|
90 | Parameters
|
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 |
|
105 | Configure `formatMessage` behavior for subsequent calls. This should be called before any code that uses `formatMessage`.
|
106 |
|
107 | Parameters
|
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 that will be used when a message translation isn't found. 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 | ### internal apis
|
124 |
|
125 | `formatMessage.number`, `formatMessage.date`, and `formatMessage.time` are used internally and are not intended for external use. If you want to just format numbers and dates, you can use the `Intl` APIs directly.
|
126 |
|
127 |
|
128 | Example Messages
|
129 | ----------------
|
130 |
|
131 | The examples provide sample output. Some assume you have configured with translations.
|
132 |
|
133 | ### Simple messages with no placeholders
|
134 |
|
135 | ```js
|
136 | formatMessage('My Collections')
|
137 | // "Minhas Coleções"
|
138 | ```
|
139 |
|
140 | ### Simple string placeholders
|
141 |
|
142 | ```js
|
143 | formatMessage('Welcome, {name}!', { name: 'Bob' });
|
144 | // "Bem Vindo, Bob!"
|
145 | ```
|
146 |
|
147 | ### Complex number, date, and time placeholders
|
148 |
|
149 | ```js
|
150 | formatMessage('{ n, number, percent }', { n: 0.1 });
|
151 | // "10%"
|
152 |
|
153 | formatMessage('{ shorty, date, short }', { shorty: new Date() });
|
154 | // "1/1/15"
|
155 |
|
156 | formatMessage('You took {n,number} pictures since {d,date} {d,time}', { n: 4000, d: new Date() });
|
157 | // "You took 4,000 pictures since Jan 1, 2015 9:33:04 AM"
|
158 | ```
|
159 |
|
160 | ### Complex string with select and plural in ES6
|
161 |
|
162 | ```js
|
163 | import formatMessage from 'format-message'
|
164 |
|
165 | // using a template string for multiline, NOT for interpolation
|
166 | formatMessage(`On { date, date, short } {name} ate {
|
167 | numBananas, plural,
|
168 | =0 {no bananas}
|
169 | =1 {a banana}
|
170 | =2 {a pair of bananas}
|
171 | other {# bananas}
|
172 | } {
|
173 | gender, select,
|
174 | male {at his house.}
|
175 | female {at her house.}
|
176 | other {at their house.}
|
177 | }`, {
|
178 | date: new Date(),
|
179 | name: 'Curious George',
|
180 | gender: 'male',
|
181 | numBananas: 27
|
182 | })
|
183 | // "On 1/1/15 Curious George ate 27 bananas at his house."
|
184 | ```
|
185 |
|
186 |
|
187 | License
|
188 | -------
|
189 |
|
190 | This software is free to use under the MIT license. See the [LICENSE-MIT file][LICENSE] for license text and copyright information.
|
191 |
|
192 |
|
193 | [logo]: https://cdn.rawgit.com/format-message/format-message/5ecbfe3/logo.svg
|
194 | [npm]: https://www.npmjs.org/package/format-message
|
195 | [npm-image]: https://img.shields.io/npm/v/format-message.svg
|
196 | [build]: https://travis-ci.org/format-message/format-message
|
197 | [build-image]: https://img.shields.io/travis/format-message/format-message.svg
|
198 | [style]: https://github.com/feross/standard
|
199 | [style-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg
|
200 | [license-image]: https://img.shields.io/npm/l/format-message.svg
|
201 | [caniuse-intl]: http://caniuse.com/#feat=internationalization
|
202 | [icu-message]: http://userguide.icu-project.org/formatparse/messages
|
203 | [icu-cpp]: http://icu-project.org/apiref/icu4c/classicu_1_1MessageFormat.html
|
204 | [icu-php]: http://php.net/manual/en/class.messageformatter.php
|
205 | [icu-java]: http://icu-project.org/apiref/icu4j/
|
206 | [intl]: https://github.com/andyearnshaw/Intl.js
|
207 | [icu-for-translators]: http://format-message.github.io/icu-message-format-for-translators/
|
208 | [format-message-generate-id]: https://github.com/format-message/format-message/tree/master/packages/format-message-generate-id
|
209 | [message-format]: https://github.com/format-message/message-format
|
210 | [mdn-intl-datetimeformat]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
|
211 | [mdn-intl-numberformat]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
|
212 | [LICENSE]: https://github.com/format-message/format-message/blob/master/LICENSE-MIT
|