@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/translations
Usage
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 instance
Translator 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;
}
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago