@jochlain/translations v2.0.0
Translation module
From a catalog of translations, translate your content with or not parameters.
Can work with Symfony translations structure in Node environment and/or with Webpack using Babel.
See how to integrate with :
Summary
Installation
npm install --save @jochlain/translationsUsage
const CATALOG = {
en: {
messages: {
hello: "Hi",
"translations.are.incredible": 'The translations are incredible.',
very: { compound: { key: "The compound key" } },
},
forms: {
"This field is required.": "This field is required."
},
},
es: {
messages: {
hello: "Holà",
"translations.are.incredible": 'Las traducciones son increíbles.',
very: { compound: { key: "La llave compuesta" } },
},
forms: {
"This field is required.": "Este campo es obligatorio.",
},
},
fr: {
messages: {
hello: "Bonjour",
"translations.are.incredible": "Les traductions sont incroyables.",
very: { compound: { key: "La clé composée" } },
},
forms: {
"This field is required.": "Ce champs est obligatoire.",
},
},
it: {
messages: {
hello: "Ciao",
"translations.are.incredible": 'Le traduzioni sono incredibili.',
very: { compound: { key: "La chiave composta" } },
},
forms: {
"This field is required.": "Questo campo è richiesto.",
},
},
};import Translator, { translate } from "@jochlain/translations";
const translator = Translator(CATALOG);
console.log(translator.translate('hello')); // => "Hi"
console.log(translator.translate('hello', null, null, 'fr')); // => "Bonjour"
// With unknown informations
console.log(translator.translate('hello', null, 'forms')); // => "hello"
console.log(translator.translate('hello', null, 'validators')); // => "hello"
console.log(translator.translate('hello', null, null, 'ar')); // => "hello"
// Compound key
console.log(translator.translate('very.compound.key')); // => "The compound key"
// Fake compound key
console.log(translator.translate('translations.are.incredible')); // => "The translations are incredible."
// Usage of with* helper
const translatorFormsEn = translator.withDomain('forms');
const translatorFormsFr = translatorFormsEn.withLocale('fr');
console.log(translatorFormsEn.translate('This field is required.')); // => "This field is required."
console.log(translatorFormsFr.translate('This field is required.')); // => "Ce champs est obligatoire."
console.log(translate({ en: 'Hello', fr: 'Bonjour' })); // => "Hello"
console.log(translate({ en: 'Hello', fr: 'Bonjour' }, null, 'fr')); // => "Bonjour"For more usage sample see Jest test
Intl integration
Intl installation
npm i -S intl-messageformat
Usage with Intl
import Translator from "@jochlain/translations";
import { IntlMessageFormat } from "intl-messageformat";
const formatter = { format: (message, replacements, locale) => (new IntlMessageFormat(message, locale).format(replacements)) };
const translator = Translator(CATALOG, { formatter });Questions and answers
Why ?
Because I can't found a simple and secured way to send translations to front shared by server.
Who ?
For little project directly or bigger project with babel macro.
- Load translations from JSON files
- Load translations from YAML files
Where ?
In a node / browser / compiled / SSR.
Documentation
Types
type ReplacementType = { [key: string]: number|string };
type FormatType = (message: string, replacements: ReplacementType, locale: string) => string;
type FormatterType = { format: FormatType };
type CatalogType = { [key: string]: string|CatalogType };
type TranslationType = { [locale: string]: { [domain: string]: CatalogType } };
type OptionsType = { locale?: string, domain?: string, formatter?: FormatterType };Constants
DEFAULT_DOMAIN="messages"
DEFAULT_LOCALE="en"Module
| Name | Type | Description |
|---|---|---|
| default | Proxy<Translator> | If call like a function it calls create static method, else is the Translation class. |
| DEFAULT_DOMAIN | string | Module constant |
| DEFAULT_LOCALE | string | Module constant |
| Translator | Proxy<Translator> | The default export of the module |
| createTranslator | Function | Static method create |
| formatMessage | Function | Default format method |
| getCatalogValue | Function | Static method getCatalogValue |
| mergeCatalogs | Function | Static method mergeCatalogs |
| translate | Function | Static method translate |
Translator proxy
If is applied like below, it calls static method create. If is constructed like below, is calls the constructor.
import Translator from "@jochlain/translations";
const domain = 'messages';
const locale = 'en';
const catalogs = new Map();
catalogs.set('messages-en', { hello: 'Hello' });
const translations = { en: { messages: { hello: 'Hello' } } };
const translator_applied = Translator(translations, { domain, locale }); // call static method create.
const translator_constructed = new Translator(catalogs, { domain, locale }); // construct new instanceTranslator class
Members
| Name | Type | Default | Description |
|---|---|---|---|
| catalogs | Map<string, CatalogType> | [] | Translation catalogs |
| fallbackDomain | string | 'messages' | Default domain used in translate |
| fallbackLocale | string | 'en' | Default locale used in translate |
| formatter | FormatterType | { format } | Formate message with locale and replacements |
| translations | TranslationType | {} | Translation catalogs formatted as object |
Constructor
Parameters
| Name | Type | Default |
|---|---|---|
| catalogs | Map<string, CatalogType> | Empty Map |
| options | OptionsType | {} |
Return value
| Type |
|---|
| Translator |
Static methods
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| translations | TranslationType | {} | Translation catalogs by locale and domains |
| options | OptionsType | {} | Options to set member default value |
Return value
| Type | Description |
|---|---|
| Translator | A translator instance |
Browse catalog to find value assigned to key
Parameters
| Name | Type |
|---|---|
| catalog | CatalogType | undefined |
| key | string |
Return value
| Type | Description |
|---|---|
| string | The value in the catalog attached to the key or the key if not found |
Format a key from domain and locale.
Parameters
| Name | Type |
|---|---|
| domain | string |
| locale | string |
Return value
| Type | Description |
|---|---|
| string | The formatted key |
Deep merge many catalogs
Parameters
| Name | Type |
|---|---|
| target | ?CatalogType |
| sources | CatalogType[] |
Return value
| Type | Description |
|---|---|
| CatalogType | A catalog with deep merged values |
Get domain and locale from key.
Parameters
| Name | Type |
|---|---|
| key | string |
Return value
| Type | Description |
|---|---|
| string, string | The domain and the locale |
Translate a message from a simple catalog
Parameters
| Name | Type | Default |
|---|---|---|
| catalog | { locale: string: string } | {} |
| replacements | ?ReplacementType | {} |
| locale | string | DEFAULT_LOCALE |
| formatter | FormatterType | { format } |
Return value
| Type | Description |
|---|---|
| string | The translated message |
Methods
Add a catalog to translations map
Parameters
| Name | Type | Default |
|---|---|---|
| catalog | CatalogType | {} |
| locale | string | this.fallbackLocale |
| domain | string | this.fallbackDomain |
Return value
| Type | Description |
|---|---|
| Translator | The translator instance to chain methods |
Get the catalog attached to domain and locale in catalogs map.
If locale is like en_US it looks first for a en_US catalog and if not looks for a en catalog.
Parameters
| Name | Type | Default |
|---|---|---|
| locale | string | this.fallbackLocale |
| domain | string | this.fallbackDomain |
Return value
| Type | Description |
|---|---|
| CatalogType | undefined | The catalog of messages attached to domain and locale |
Get all domains fill in catalogs map
Return value
| Type | Description |
|---|---|
| string[] | The domains |
Get all locales fill in catalogs map
Return value
| Type | Description |
|---|---|
| string[] | The locales |
Get message attached to key in catalog attached to domain and locale in catalogs.
See getCatalog and getCatalogValue
Parameters
| Name | Type | Default |
|---|---|---|
| key | string | none |
| locale | string | this.fallbackLocale |
| domain | string | this.fallbackDomain |
Return value
| Type | Description |
|---|---|
| string | Message attached to key or key if not found |
Get messages attached to key
Parameters
| Name | Type | Default |
|---|---|---|
| key | string | none |
| domain | string | this.fallbackDomain |
Return value
| Type | Description |
|---|---|
| { locale: string :string } | A collection of messages by locale |
Set the fallbackDomain member
Parameters
| Name | Type | Default |
|---|---|---|
| domain | string | DEFAULT_DOMAIN |
Return value
| Type | Description |
|---|---|
| Translator | The translator instance to chain methods |
Set the fallbackLocale member
Parameters
| Name | Type | Default |
|---|---|---|
| locale | string | DEFAULT_LOCALE |
Return value
| Type | Description |
|---|---|
| Translator | The translator instance to chain methods |
Set the formatter member
Parameters
| Name | Type | Default |
|---|---|---|
| formatter | FormatterType | { format } |
Return value
| Type | Description |
|---|---|
| Translator | The translator instance to chain methods |
Set the formatter member
Parameters
| Name | Type | Default |
|---|---|---|
| translations | TranslationType | The translations to append |
Return value
| Type | Description |
|---|---|
| Translator | The translator instance to chain methods |
Clone instance with fallbackDomain domain parameter
Parameters
| Name | Type |
|---|---|
| domain | string |
Return value
| Type | Description |
|---|---|
| Translator | A new translator instance |
Clone instance with formatter
Parameters
| Name | Type |
|---|---|
| formatter | FormatterType |
Return value
| Type | Description |
|---|---|
| Translator | A new translator instance |
Clone instance with fallbackLocale locale parameter
Parameters
| Name | Type |
|---|---|
| locale | string |
Return value
| Type | Description |
|---|---|
| Translator | A new translator instance |
Clone instance with domain, formatter, locale.
Parameters
| Name | Type | Default |
|---|---|---|
| domain | string | this.fallbackDomain |
| locale | string | this.fallbackLocale |
| formatter | FormatterType | this.formatter |
Return value
| Type | Description |
|---|---|
| Translator | A new translator instance |
Default format method
By default, format method search each replacement key with a RegExp and replace them by their values.
That's the next part I'm going to look at.
function format(message: string, replacements: ReplacementType, locale: string = DEFAULT_LOCALE) {
let result = message;
for (let keys = Object.keys(replacements), idx = 0; idx < keys.length; idx++) {
result = result.replace(new RegExp(`${keys[idx]}`, 'g'), String(replacements[keys[idx]]));
}
return result;
}3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago