AdGuard Translate
Simple internationalization library with React integration
Installation
npm
npm install @adguard/translate
Yarn
yarn add @adguard/translate
Usage
Messages format
Library supports messages with placeholders, tags and plural forms
Placeholders
Placeholders should be wrapped in %
mark
e.g.
"agreement_consent": {
"message": "Servers number %count%",
}
Tags support
Library supports open/close tags, and their values should be provided in the translate
method
e.g.
<a>link</a> to the text
and void tags
e.g.
<img src="server.jpg" >
Default list of tags
Next tags are not required in the translate
, because they are provided by default
<b>, <p>, <strong>, <tt>, <s>, <i>,
Plural strings
Library supports plural strings translation.
e.g.
Нет серверов | %count% сервер | %count% сервера | %count% серверов
Plural strings should follow simple rules.
- Plural forms should be divided by
|
. - Plural forms count should correspond to the language plural forms count (table) + 1 (zero form).
- If first plural form is omitted, for the zero form you'll get empty string
| %count% сервер | %count% сервера | %count% серверов
translate
// import library
import { translate } from '@adguard/translate'
// create i18n object which implements I18nInterface:
interface I18nInterface {
/**
* Returns message by key for current locale
* @param key
*/
getMessage(key: string): string;
/**
* Returns current locale code
* Locale codes should be in the list of `Locale`s
*/
getUILanguage(): Locale;
/**
* Returns base locale message
* @param key
*/
getBaseMessage(key: string): string;
/**
* Returns base locale code
*/
getBaseUILanguage(): Locale;
}
// in the browser extension it will be "browser.i18n"
// create translate function
const translator = translate.createTranslator(i18n)
// e.g.
// string to translate:
// "agreement_consent": {
// "message": "You agree to our <eula>EULA</eula>",
// }
createTranslator
This method can be used to translate simple strings and Vue template strings
const translator = translate.createTranslator(browser.i18n);
const translatedString = translator.getMessage('agreement_consent', {
eula: (chunks) => `<button class="privacy-link">${chunks}</button>`,
});
console.log(translatedString); // <button class="privacy-link">EULA</button>
createReactTranslator
const reactTranslator = translate.createReactTranslator(browser.i18n, React);
<div>
{reactTranslator.getMessage('agreement_consent', {
eula: (chunks) => (
<button
className="auth__term"
onClick={handleEulaClick}
>
{chunks}
</button>
),
})}
</div>
validator
// import library
import { validator } from '@adguard/translate'
isTranslationValid
const baseMessage = 'test string <a>has node</a>';
const targetMessage = 'тестовая строка <a>с нодой</a>';
validator.isTranslationValid(baseMessage, targetMessage); // true
isPluralFormValid
validator.isPluralFormValid(%count% серверов | %count% сервер | %count% сервера | %count% серверов, 'ru', "servers_count"); // true, all 4 plural forms are provided
validator.isPluralFormValid(%count% сервера | %count% серверов, 'ru', "servers_count"); // false, ru locale awaits for 4 plural forms provided
API
createTranslator
/**
* Creates translator instance strings, by default for simple strings
* @param i18n - function which returns translated message by key
* @param messageConstructor - function that will collect messages
* @param values - map with default values for tag converters
*/
const createTranslator = (
i18n: I18nInterface,
messageConstructor?: MessageConstructorInterface,
values?: ValuesAny
): Translator
createReactTranslator
/**
* Creates translation function for strings used in the React components
* We do not import React directly, because translator module can be used
* in the modules without React too
*
*
* @param i18n - object with methods which get translated message by key and return current locale
* @param React - instance of react library
*/
const createReactTranslator = (i18n: I18nInterface, React: ReactCustom): Translator
getMessage
/**
* Retrieves message and translates it, substituting parameters where necessary
* @param key - translation message key
* @param params - values used to substitute placeholders and tags
*/
public getMessage(key: string, params: ValuesAny = {}): T {
getPlural
/**
* Retrieves correct plural form and translates it
* @param key - translation message key
* @param number - plural form number
* @param params - values used to substitute placeholders or tags if necessary,
* if params has "count" property it will be overridden by number (plural form number)
*/
public getPlural(key: string, number: number, params: ValuesAny = {}): T {
isTranslationValid
/**
* Validates translation against base string by AST (abstract syntax tree) structure.
*
* @param baseMessage Base message.
* @param translatedMessage Translated message.
* @param locale Locale of `translatedMessage`.
*
* @returns True if translated message is valid, false otherwise:
* - if base message has no plural forms, it will return true if AST structures are same;
* - if base message has plural forms, first of all
* the function checks if the number of plural forms is correct for the `locale`,
* and then it validates AST plural forms structures for base and translated messages.
*
* @throws Error for invalid tags in base or translated messages,
* or if translated message has invalid plural forms.
*/
const isTranslationValid = (baseMessage: string, translatedMessage: string, locale: Locale): boolean
isPluralFormValid
/**
* Checks if plural forms are valid.
*
* @param targetStr Translated message with plural forms.
* @param locale Locale.
* @param key Optional, message key, used for clearer log message.
*
* @returns True if plural forms are valid, false otherwise.
*/
const isPluralFormValid = (targetStr: string, locale: Locale, key: string): boolean
Development
Use yarn to build the library
Build
To build the library run:
yarn build
Build result would be in the dist
directory
Lint
To check lint errors run in terminal:
yarn lint
Test
The library uses jest for running unit-tests. To launch the tests, run the following command in the terminal:
yarn test
Docs
To build documentation, run the following command in the terminal:
yarn docs
TODO
- [ ] Create Vue plugin
- [ ] Add utility to check if code contains unused or redundant translation messages
License
MIT