1 | BabelFish - human friendly i18n for JS
|
2 | ======================================
|
3 |
|
4 | [![Build Status](https://travis-ci.org/nodeca/babelfish.svg?branch=master)](https://travis-ci.org/nodeca/babelfish)
|
5 | [![NPM version](https://img.shields.io/npm/v/babelfish.svg?style=flat)](https://www.npmjs.org/package/babelfish)
|
6 | [![Coverage Status](https://img.shields.io/coveralls/nodeca/babelfish/master.svg?style=flat)](https://coveralls.io/r/nodeca/babelfish?branch=master)
|
7 |
|
8 | > Internationalisation with easy syntax for node.js and browser.
|
9 |
|
10 | Classic solutions use multiple phrases for plurals. `Babelfish` defines plurals
|
11 | inline instead - that's more compact, and easy for programmers. Also, phrases
|
12 | are grouped into nested scopes, like in Ruby.
|
13 |
|
14 | `BabelFish` supports all plural rules from [unicode CLDR](http://cldr.unicode.org/index/charts)
|
15 | (via [plurals-cldr](https://github.com/nodeca/plurals-cldr)).
|
16 |
|
17 |
|
18 | ### Installation
|
19 |
|
20 | __node.js:__
|
21 |
|
22 | ```bash
|
23 | $ npm install babelfish
|
24 | ```
|
25 |
|
26 | __browser:__
|
27 |
|
28 | ```bash
|
29 | $ bower install babelfish
|
30 | ```
|
31 |
|
32 | Use [es5-shim](https://github.com/es-shims/es5-shim) for old browsers
|
33 | compatibility.
|
34 |
|
35 |
|
36 | ### Phrases Syntax
|
37 |
|
38 | - `#{varname}` Echoes value of variable
|
39 | - `((Singular|Plural1|Plural2)):count` Plural form
|
40 |
|
41 | example:
|
42 |
|
43 | - `А у меня в кармане #{nails_count} ((гвоздь|гвоздя|гвоздей)):nails_count`
|
44 |
|
45 | You can also omit anchor variable for plurals, by default it will be `count`.
|
46 | Thus following variants are equal:
|
47 |
|
48 | - `I have #{count} ((nail|nails))`
|
49 | - `I have #{count} ((nail|nails)):count`
|
50 |
|
51 | Also you can use variables in plural parts:
|
52 |
|
53 | - `I have ((#{count} nail|#{count} nails))`
|
54 |
|
55 | Need special zero form or overwrite any specific value? No problems:
|
56 |
|
57 | - `I have ((=0 no nails|#{count} nail|#{count} nails))`
|
58 |
|
59 |
|
60 | ##### Escape chars
|
61 |
|
62 | If you need `#{`, `((`, `|` or `))` somewhere in text, where it can be considered
|
63 | as markup part - just escape them with `\`.
|
64 |
|
65 |
|
66 | ##### Example with YAML
|
67 |
|
68 | As BabelFish flatten scopes, it's really fun and nice to store translations in
|
69 | YAML files:
|
70 |
|
71 | ```yaml
|
72 | ---
|
73 | ru-RU:
|
74 | profile: Профиль
|
75 | forums: Форумы
|
76 | apps:
|
77 | forums:
|
78 | new_topic: Новая тема
|
79 | last_post:
|
80 | title : Последнее сообщение
|
81 | by : от
|
82 | demo:
|
83 | apples: "На столе лежит #{count} ((яблоко|яблока|яблок))"
|
84 | ```
|
85 |
|
86 | ### Usage
|
87 |
|
88 | ```javascript
|
89 | // Create new instance of BabelFish with default language/locale: 'en-GB'
|
90 | var BabelFish = require('babelfish');
|
91 | var i18n = new BabelFish('en-GB');
|
92 |
|
93 |
|
94 | // Fill in some phrases
|
95 | i18n.addPhrase('en-GB', 'demo.hello', 'Hello, #{user.name}.');
|
96 | i18n.addPhrase('en-GB', 'demo.conv.wazup', 'Whats up?');
|
97 | i18n.addPhrase('en-GB', 'demo.conv.alright', 'Alright, man!');
|
98 | i18n.addPhrase('en-GB', 'demo.coerce', 'Total: #{count}.');
|
99 |
|
100 | i18n.addPhrase('ru-RU', 'demo.hello', 'Привет, #{user.name}.');
|
101 | i18n.addPhrase('ru-RU', 'demo.conv.wazup', 'Как дела?');
|
102 |
|
103 | i18n.addPhrase('uk-UA', 'demo.hello', 'Здоровенькі були, #{user.name}.');
|
104 |
|
105 |
|
106 | // Set locale fallback to use the most appropriate translation when possible
|
107 | i18n.setFallback('uk-UA', 'ru-RU');
|
108 |
|
109 |
|
110 | // Translate
|
111 | var params = {user: {name: 'ixti'}};
|
112 |
|
113 | i18n.t('ru-RU', 'demo.hello', params); // -> 'Привет, ixti.'
|
114 | i18n.t('ru-RU', 'demo.conv.wazup'); // -> 'Как дела?'
|
115 | i18n.t('ru-RU', 'demo.conv.alright'); // -> 'Alright, man!'
|
116 |
|
117 | i18n.t('uk-UA', 'demo.hello', params); // -> 'Здоровенькі були, ixti.'
|
118 | i18n.t('uk-UA', 'demo.conv.wazup'); // -> 'Как дела?'
|
119 | i18n.t('uk-UA', 'demo.conv.alright'); // -> 'Alright, man!'
|
120 |
|
121 | // When params is number or strings, it will be coerced to
|
122 | // `{ count: XXX, value: XXX }` - use any of those in phrase.
|
123 | i18n.t('en-GB', 'demo.coerce', 5); // -> 'Total: 5.'
|
124 |
|
125 |
|
126 | // You may wish to "dump" translations to load in browser later
|
127 | // Dump will include all fallback translations and fallback rules
|
128 | var locale_dump = i18n.stringify('ru-RU');
|
129 |
|
130 | var i18n_new = require('babelfish')('en-GB'); // init without `new` also works
|
131 | i18n_new.load(locale_dump);
|
132 |
|
133 |
|
134 | // Use objects instead of strings (object/array/number/boolean) - can be
|
135 | // useful to prepare bulk data for external libraries.
|
136 | // Note, only JSON-supported types are ok (no date & regex)
|
137 | i18n.addPhrase('en-GB', 'demo.boolean', true);
|
138 | i18n.addPhrase('en-GB', 'demo.number', 123);
|
139 | i18n.addPhrase('en-GB', 'demo.array', [1, 2, 3]);
|
140 | // fourth param required for hashes (objects) to disable flattening,
|
141 | // other types are autodetected
|
142 | i18n.addPhrase('en-GB', 'demo.array', { foo:1, bar:"2" }, false);
|
143 | ```
|
144 |
|
145 |
|
146 | ### Implementations in other languages
|
147 |
|
148 | - Perl - [Locale::Babelfish](https://metacpan.org/pod/Locale::Babelfish)
|
149 | - Ruby - https://github.com/regru/babelfish-ruby
|
150 |
|
151 |
|
152 | ### License
|
153 |
|
154 | View the [LICENSE](https://github.com/nodeca/babelfish/blob/master/LICENSE) file (MIT).
|