UNPKG

15.5 kBMarkdownView Raw
1# ![format-message][logo]
2
3> Write i18n messages inline. Transpile translations.
4
5[![npm Version][npm-image]][npm]
6[![Dependency Status][deps-image]][deps]
7[![Dev Dependency Status][dev-deps-image]][dev-deps]
8[![Build Status][build-image]][build]
9
10[![JS Standard Style][style-image]][style]
11[![MIT License][license-image]][LICENSE]
12
13
14Quick Start
15-----------
16
17`npm install format-message --save` adds the library to `node_modules`. You can then use it as follows:
18
19```js
20var formatMessage = require('format-message');
21
22var message = formatMessage('Hello { place }!', { place:'World' });
23```
24
25You can configure your translations at runtime (typical for server-side use), or transpile your code for better performance in repeated use on the client.
26
27`format-message` relies on the ECMAScript Internationalization API 1.0 (`Intl`) for formatting `number`, `date`, and `time` arguments. If you are in an environment missing these ([like node <= 0.12, IE < 11, or Safari][caniuse-intl]) you'll want to use a [polyfill][intl]. Otherwise `format-message` falls back on `toLocaleString` methods, which are most likely just aliases for `toString`.
28
29
30Format Overview
31---------------
32
33The [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].
34
35`format-message` provides a way to write your default (often English) messages as literals in your source, and then scrape out the default patterns and transpile your source with fast inline code for formatting the translated message patterns.
36
37This relies on [message-format][message-format] for parsing and formatting ICU messages, and [babel][babel] for transpiling the source code.
38
39### Supported ICU Formats
40
41See [message-format][message-format] for supported ICU formats.
42
43### Quoting escaping rules
44
45See the [ICU site][icu-message] and [message-format][message-format] for details on how to escape special characters in your messages.
46
47### Loading locale data
48
49`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.
50
51
52API
53---
54
55### `formatMessage`
56
57```js
58var formatMessage = require('format-message')
59// or
60import formatMessage from 'format-message'
61
62formatMessage(pattern[, args[, locales]])
63```
64
65Translate and format the message with the given pattern and arguments.
66
67Parameters
68
69- `pattern` is a properly formatted ICU Message Format pattern. A poorly formatted pattern will cause an `Error` to be thrown.
70 - The pattern is used as a key into the `translate` function you provide in configuration, and is also used as the fallback if no translation is returned, or `translate` has not been configured
71 - If `pattern` is not a string literal, the function cannot be transpiled at build time.
72- `args` is an object containing the values to replace placeholders with. Required if the pattern contains placeholders.
73- `locales` is an optional string with a BCP 47 language tag, or an array of such strings.
74 - The locales are also passed into the `translate` function and indicate the desired destination language.
75 - If `locales` is not a string literal, the function cannot be transpiled at build time.
76
77### `formatMessage.setup`
78
79```js
80formatMessage.setup(options)
81```
82
83Configure `formatMessage` behavior for subsequent calls. This should be called before any code that uses `formatMessage`.
84
85Parameters
86
87- `options` is an object containing the following config values:
88 - `cache` is whether message, number, and date formatters are cached. Defaults to `true`
89 - `locale` is the default locale to use when no locale is passed to `formatMessage`. Defaults to `"en"`.
90 - `translate(pattern, locales)` is a function to translate messages. It should return the pattern translated for the specified locale.
91 - `pattern` is the message pattern to translate.
92 - `locale` is a string with a BCP 47 language tag, or an array of such strings.
93 - `missingReplacement` is a string that will be used when a message translation isn't found. By default the source message is used.
94 - `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.
95 - `formats` is an object containing objects that define placeholder styles `{ name, type, style }`:
96 - `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 seconds argument.
97 - `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 seconds argument.
98 - `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 seconds argument.
99
100### `formatMessage.translate`
101
102```js
103formatMessage.translate(pattern[, locales])
104```
105
106Use the currently configured `translate` to get the locale-specific pattern. Note that this can also be linted, extracted, and inlined if the `pattern` is a literal.
107
108Parameters
109
110- `pattern` is a properly formatted ICU Message Format pattern.
111- `locales` is an optional string with a BCP 47 language tag, or an array of such strings.
112 - If not specified, the currently configured `locale` will be used.
113
114### internal apis
115
116`formatMessage.number`, `formatMessage.date`, and `formatMessage.time` are used internally and are not intended for external use. Because these appear in the transpiled code, transpiling does not remove the need to properly define `formatMessage` through `require` or `import`.
117
118
119Transpiled Messages
120--------
121
122The examples provide sample transpiler output. This output is not meant to be 100% exact, but to give a general idea of what the transpiler does.
123
124### Simple messages with no placeholders
125
126```js
127formatMessage('My Collections')
128
129// transpiles to translated literal
130"Minhas Coleções"
131```
132
133### Simple string placeholders
134
135```js
136formatMessage('Welcome, {name}!', { name: userName });
137
138// messages with simple placeholders transpiles to concatenated strings
139"Bem Vindo, " + userName + "!" // Bem Vindo, Bob!
140```
141
142### Complex number, date, and time placeholders
143
144```js
145formatMessage('{ n, number, percent }', { n:0.1 });
146
147// transpiles to just the number call
148formatMessage.number("en", 0.1, "percent") // "10%"
149
150
151formatMessage('{ shorty, date, short }', { shorty:new Date() });
152
153// transpiles to just the date call
154formatMessage.date("en", new Date(), "short") // "1/1/15"
155
156
157formatMessage('You took {n,number} pictures since {d,date} {d,time}', { n:4000, d:new Date() });
158
159// transpiles to a function call, with the function defined at the top level
160$$_you_took_n_number_pictures_123456({ n:4000, d:new Date() })
161...
162function $$_you_took_n_number_pictures_123456(args) {
163 return "You took " + formatMessage.number("en", args["n"]) + " pictures since " + formatMessage.date("en", args["d"]) + " " + formatMessage.time("en", args["d"])
164} // "You took 4,000 pictures since Jan 1, 2015 9:33:04 AM"
165```
166
167### Complex string with select and plural in ES6
168
169```js
170import formatMessage from 'format-message'
171
172// using a template string for multiline, no interpolation
173let formatMessage(`On { date, date, short } {name} ate {
174 numBananas, plural,
175 =0 {no bananas}
176 =1 {a banana}
177 =2 {a pair of bananas}
178 other {# bananas}
179 } {
180 gender, select,
181 male {at his house.}
182 female {at her house.}
183 other {at their house.}
184 }`, {
185 date: new Date(),
186 name: 'Curious George',
187 gender: 'male',
188 numBananas: 27
189})
190
191// transpiles to a function call, with the function defined at the top level
192$$_on_date_date_short_name_ate_123456({ n:4000, d:new Date() })
193...
194function $$_on_date_date_short_name_ate_123456(args) {
195 return ...
196}
197// en-US: "On 1/1/15 Curious George ate 27 bananas at his house."
198```
199
200### Current Optimizations
201
202* Calls with no placeholders in the message become string literals.
203* Calls with no `plural`, `select`, or `selectordinal` in the message, and an object literal with variables or literals for property values become concatentated strings and variables.
204
205All other cases result in a function call, with the function declaration somewhere at the top level of the file.
206
207
208CLI Tools
209---------
210
211All of the command line tools will look for `require`ing or `import`ing `format-message` in your source files to determine the local name of the `formatMessage` function. Then they will either check for problems, extract the original message patterns, or replace the call as follows:
212
213### format-message lint
214
215#### Usage: `format-message lint [options] [files...]`
216
217find message patterns in files and verify there are no obvious problems
218
219#### Options:
220
221 -h, --help output usage information
222 -n, --function-name [name] find function calls with this name [formatMessage]
223 --no-auto disables auto-detecting the function name from import or require calls
224 -k, --key-type [type] derived key from source pattern literal|normalized|underscored|underscored_crc32 [underscored_crc32]
225 -t, --translations [path] location of the JSON file with message translations, if specified, translations are also checked for errors
226 -f, --filename [filename] filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]
227
228#### Examples:
229
230lint the src js files, with `__` as the function name used instead of `formatMessage`
231
232 format-message lint -n __ src/**/*.js
233
234lint the src js files and translations
235
236 format-message lint -t i18n/pt-BR.json src/**/*.js
237
238
239### format-message extract
240
241#### Usage: `format-message extract [options] [files...]`
242
243find and list all message patterns in files
244
245#### Options:
246
247 -h, --help output usage information
248 -n, --function-name [name] find function calls with this name [formatMessage]
249 --no-auto disables auto-detecting the function name from import or require calls
250 -k, --key-type [type] derived key from source pattern (literal | normalized | underscored | underscored_crc32) [underscored_crc32]
251 -l, --locale [locale] BCP 47 language tags specifying the source default locale [en]
252 -o, --out-file [out] write messages JSON object to this file instead of to stdout
253
254#### Examples:
255
256extract patterns from src js files, dump json to `stdout`. This can be helpful to get familiar with how `--key-type` and `--locale` change the json output.
257
258 format-message extract src/**/*.js
259
260extract patterns from `stdin`, dump to file.
261
262 someTranspiler src/*.js | format-message extract -o locales/en.json
263
264
265### format-message inline
266
267#### Usage: `format-message inline [options] [files...]`
268
269find and replace message pattern calls in files with translations
270
271#### Options:
272
273 -h, --help output usage information
274 -n, --function-name [name] find function calls with this name [formatMessage]
275 --no-auto disables auto-detecting the function name from import or require calls
276 -k, --key-type [type] derived key from source pattern (literal | normalized | underscored | underscored_crc32) [underscored_crc32]
277 -l, --locale [locale] BCP 47 language tags specifying the target locale [en]
278 -t, --translations [path] location of the JSON file with message translations
279 -e, --missing-translation [behavior] behavior when --translations is specified, but a translated pattern is missing (error | warning | ignore) [error]
280 -m, --missing-replacement [pattern] pattern to inline when a translated pattern is missing, defaults to the source pattern
281 -i, --source-maps-inline append sourceMappingURL comment to bottom of code
282 -s, --source-maps save source map alongside the compiled code
283 -f, --filename [filename] filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]
284 -o, --out-file [out] compile all input files into a single file
285 -d, --out-dir [out] compile an input directory of modules into an output directory
286 -r, --root [path] remove root path for source filename in output directory [cwd]
287
288#### Examples:
289
290create locale-specific client bundles with source maps
291
292 format-message inline src/**/*.js -s -l de -t translations.json -o dist/bundle.de.js
293 format-message inline src/**/*.js -s -l en -t translations.json -o dist/bundle.en.js
294 format-message inline src/**/*.js -s -l es -t translations.json -o dist/bundle.es.js
295 format-message inline src/**/*.js -s -l pt -t translations.json -o dist/bundle.pt.js
296 ...
297
298inline without translating multiple files that used `var __ = require('format-message')`
299
300 format-message inline -d dist -r src -n __ src/*.js lib/*.js component/**/*.js
301
302
303License
304-------
305
306This software is free to use under the MIT license. See the [LICENSE-MIT file][LICENSE] for license text and copyright information.
307
308
309[logo]: https://cdn.rawgit.com/format-message/format-message/446d303/src/logo/format-message.svg
310[npm]: https://www.npmjs.org/package/format-message
311[npm-image]: https://img.shields.io/npm/v/format-message.svg
312[deps]: https://david-dm.org/format-message/format-message
313[deps-image]: https://img.shields.io/david/format-message/format-message.svg
314[dev-deps]: https://david-dm.org/format-message/format-message#info=devDependencies
315[dev-deps-image]: https://img.shields.io/david/dev/format-message/format-message.svg
316[build]: https://travis-ci.org/format-message/format-message
317[build-image]: https://img.shields.io/travis/format-message/format-message.svg
318[style]: https://github.com/feross/standard
319[style-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg
320[license-image]: https://img.shields.io/npm/l/format-message.svg
321[caniuse-intl]: http://caniuse.com/#feat=internationalization
322[icu-message]: http://userguide.icu-project.org/formatparse/messages
323[icu-cpp]: http://icu-project.org/apiref/icu4c/classicu_1_1MessageFormat.html
324[icu-php]: http://php.net/manual/en/class.messageformatter.php
325[icu-java]: http://icu-project.org/apiref/icu4j/
326[intl]: https://github.com/andyearnshaw/Intl.js
327[message-format]: https://github.com/format-message/message-format
328[babel]: https://github.com/babel/babel
329[mdn-intl-datetimeformat]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
330[mdn-intl-numberformat]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
331[LICENSE]: https://github.com/format-message/format-message/blob/master/LICENSE-MIT