Powerful and fast runtime internationalization (i18n) utility without dependencies.
- Flexible and easy to use getting translations by paths
- Nesting translation branches
- Extending branches with
@extenddirective - Defining branch fallbacks with
@anydirective - Defining branch root with
@rootdirective - Reuse keys with in-translation
<[path]>directive - Interpolation with in-translation
<=[param]>directive
Using npm:
$ npm install movaReturns translation for passed path. Path could be built with strings and arrays of strings. If the last argument is an object - it will be used as interpolation params object. Any other arguments will be ignored.
For example, all of this calls are equal:
mova('k1.k2.k3.k4.k5', { param: 'value' });
mova('k1', 'k2', 'k3', 'k4', 'k5', { param: 'value' });
mova('k1', 'k2', ['k3'], 'k4.k5', { param: 'value' });
mova('k1', ['k2', ['k3', 'k4']], 'k5', { param: 'value' });
mova('k1', ['k2', ['k3.k4']], 'k5', { param: 'value' });
mova('.', null, 'k1', NaN, ['k2', 'k3.k4'], {}, 'k5', 10, { param: 'value' });Accepts language pack and pre-compiles it for better runtime performance.
Allows you to prepare language namespace for further usage.
For example, this call:
const t = mova.nameSpace('k1', 'k2', 'k3');
t('k4', 'k5');Equals to:
mova('k1', 'k2', 'k3', 'k4', 'k5');Alias for mova.nameSpace method.
Allows you to interpolate passed params on passed string.
mova.interpolate('key1: <=key1>', { key1: 'value 1' }); // -> key1: value 1interpolationFallback arg allows to define fallback which will be used if no value passed for some param. If not specified - such params will not be interpolated.
mova.interpolate('key1: <=key1>', {}, '-'); // -> key1: -
mova.interpolate('key1: <=key1>', {}); // -> key1: <=key1>This method is used by mova main function for value interpolation.
Interpolation fallback used by default. You can redefine it if necessary:
mova.interpolationFallback = '[no value]';To use mova for i18n you have to define language pack first.
Basically it's simple object with unlimited depth of nesting, like this:
{
"key1": "value 1",
"branch": {
"key1": "branch value 1",
"innerBranch": {
"key1": "inner branch value 1"
}
}
}mova('branch.key1'); // -> 'branch value 1'Above example is very simple while real applications might need more complex solutions like extending branches, defining fallback translations, defining branch root translations, referencing other translations or interpolation.
For this purposes mova supports directives.
Allows you to define root translation for specific branch.
{
"branch": {
"@root": "Branch root"
}
}mova('branch'); // -> 'Branch root'@root directive can not be used on translation root branch.
Allows you to define a fallback translation for specific branch.
{
"branch": {
"@any": "Branch fallback",
"innerBranch": {}
}
}mova('branch.unknown.key'); // -> 'Branch fallback'
// Also works for branch root path
mova('branch'); // -> 'Branch fallback'
// But does not work for existing inner branches
mova('branch.innerBranch.unknown.key'); // -> 'branch.innerBranch.unknown.key'Allows you to extends existing branch. This directive accepts chaining, so if you will extend a branch that is extending another branch, your result branch will contain translations from both those branches.
{
"branch1": {
"@root": "Branch root",
"k1": "branch 1, value 1",
"k2": "branch 1, value 2"
},
"branch2": {
"@extends": "branch1",
"k1": "branch 2, value 1"
},
"branch3": {
"@extends": "branch2",
"@root": "Branch 2 root"
}
}mova('branch2'); // -> 'Branch root'
mova('branch2.k1'); // -> 'branch 2, value 1'
mova('branch2.k2'); // -> 'branch 1, value 2'
mova('branch3'); // -> 'Branch 2 root'
mova('branch3.k1'); // -> 'branch 2, value 1'
mova('branch3.k2'); // -> 'branch 1, value 2'You also can extend from several branches using , as paths separator in @extends directive:
{
"branch1": {
"k1": "value 1"
},
"branch2": {
"k2": "value 2"
},
"branch3": {
"@extends": "branch1, branch2"
}
}mova('branch3.k1'); // -> 'value 1'
mova('branch3.k2'); // -> 'value 2'@extends directive has some restrictions:
- You can not extend any of parent branches.
- You can not create circular extending, i.e. no branch can be both dependency and dependent at the same time for any other branch.
Allows you to reuse your translations. [path] should be replaced with absolute
path to translation or relative path to current branch prepended with .
{
"k1": "root value 1",
"branch": {
"@root": "branch root",
"k1": "branch value 1",
"k2": "reference - <k1>",
"k3": "reference - <.k1>",
"k4": "reference - <.>"
}
}mova('branch.k2'); // -> 'reference - root value 1'
mova('branch.k3'); // -> 'reference - branch value 1'
mova('branch.k4'); // -> 'reference - branch root'Allows you to interpolate some values in your translations.
{
"k1": "<=key1>",
"k2": "<k1> <=key2>"
}mova('k2', { key1: 'val1', key2: 'val2' }); // -> 'val1 val2'
mova('k2', { key1: 'val1' }); // -> 'val1 -'In second example <=key2> param was replaced with mova.interpolationFallback value
which is equal to - by default.
mova will pre-compile passed language pack before using it to increase runtime
translation performance.
So, for example, this language pack:
{
"k1": "value 1",
"base": {
"@root": "base root",
"k3": "base value 3",
"k4": "relative <.k1>"
},
"branch": {
"@extends": "base",
"@any": "branch fallback",
"k1": "branch <k1>",
"k2": "branch value 2 <=key>"
}
}Will be pre-compiled to this:
{
"k1": "value 1",
"base": "base root",
"base.k3": "base value 3",
"base.k4": "relative base.k1",
"branch": "base root",
"branch.@any": "branch fallback",
"branch.k1": "branch value 1",
"branch.k2": "branch value 2 <=key>",
"branch.k3": "base value 3",
"branch.k4": "relative branch value 1"
}So what happens during pre-compilation step:
- Resolve
@extendsdirectives - Resolve in-translation
<[path]>directives with respect to@rootand@anydirectives - Resolve
@rootdirectives - Flatten language pack to single level object with compiled paths as keys
Because of this pre-compilation mova works very fast in runtime as its flow now very simple:
- Join passed path parts with
.separator - Try to find direct value for this path or fallback for its branch
- Interpolate found value with passed named params
If no value will be found for passed path mova will return this path as result.