Skip to content
Snippets Groups Projects
Commit d71fa224 authored by Reiter, Christoph's avatar Reiter, Christoph :snake:
Browse files

common: Add an i18next API for overriding translations

Create a new instance with createInstance() and call setOverrides()
with override data to override translations.

See the tests for some examples.
parent 86f29a8d
No related branches found
No related tags found
No related merge requests found
...@@ -42,6 +42,17 @@ export function humanFileSize(bytes, si = false) { ...@@ -42,6 +42,17 @@ export function humanFileSize(bytes, si = false) {
return bytes.toFixed(1)+' '+units[u]; return bytes.toFixed(1)+' '+units[u];
} }
/**
* @param {string} namespace The namespace to override
* @returns {string} The new namespace name
*/
function getOverrideNamespace(namespace) {
// This just needs to be different to the namespace, make it special
// so it's clear what it is used for in case it ends up in some error
// message or something
return '--' + namespace + '-override';
}
/** /**
* Creates a new i18next instance that is fully initialized. * Creates a new i18next instance that is fully initialized.
* *
...@@ -54,16 +65,18 @@ export function humanFileSize(bytes, si = false) { ...@@ -54,16 +65,18 @@ export function humanFileSize(bytes, si = false) {
* @returns {i18next.i18n} A new independent i18next instance * @returns {i18next.i18n} A new independent i18next instance
*/ */
export function createInstance(languages, lng, fallback, namespace) { export function createInstance(languages, lng, fallback, namespace) {
if (namespace === undefined) if (namespace === undefined) {
namespace = 'translation'; namespace = 'translation';
}
let overrideNamespace = getOverrideNamespace(namespace);
var options = { var options = {
lng: lng, lng: lng,
fallbackLng: fallback, fallbackLng: fallback,
debug: false, debug: false,
ns: [namespace + '-override'], ns: [overrideNamespace, namespace],
defaultNS: namespace + '-override', defaultNS: namespace,
fallbackNS: [namespace], fallbackNS: namespace,
initImmediate: false, // Don't init async initImmediate: false, // Don't init async
resources: {}, resources: {},
}; };
...@@ -77,4 +90,30 @@ export function createInstance(languages, lng, fallback, namespace) { ...@@ -77,4 +90,30 @@ export function createInstance(languages, lng, fallback, namespace) {
console.assert(i18n.isInitialized); console.assert(i18n.isInitialized);
return i18n; return i18n;
} }
\ No newline at end of file
/**
* Sets translation overrides for the given i18next instance. Any previously
* applied overrides will be removed first. So calling this with an empty overrides
* object is equal to removing all overrides.
*
* @param {i18next.i18n} i18n - The i18next instance
* @param {object} overrides - The override data in the following format: "{language: {namespace: {key: value}}}"
*/
export function setOverrides(i18n, overrides) {
// We add a special namespace which gets used with priority and falls back
// to the original one. This way we an change the overrides at runtime
// and can even remove them.
let namespace = i18n.options.fallbackNS;
let overrideNamespace = getOverrideNamespace(namespace);
let hasOverrides = false;
for(let lng of i18n.languages) {
i18n.removeResourceBundle(lng, overrideNamespace);
if (overrides[lng] === undefined || overrides[lng][namespace] === undefined)
continue;
let resources = overrides[lng][namespace];
hasOverrides = true;
i18n.addResourceBundle(lng, overrideNamespace, resources);
}
i18n.setDefaultNamespace(hasOverrides ? overrideNamespace : namespace);
}
...@@ -47,4 +47,25 @@ suite('i18next', () => { ...@@ -47,4 +47,25 @@ suite('i18next', () => {
assert.equal(i18next.numberFormat(inst, 1.25), '1.25'); assert.equal(i18next.numberFormat(inst, 1.25), '1.25');
assert.equal(i18next.numberFormat(inst, 1234), '1,234'); assert.equal(i18next.numberFormat(inst, 1234), '1,234');
}); });
test('overrides', () => {
let namespace = 'ns';
var inst = i18next.createInstance({en: {foo: 'bar'}}, 'en', 'en', namespace);
assert.equal(inst.t('foo'), 'bar');
assert.equal(inst.t('quux'), 'quux');
i18next.setOverrides(inst, {en: {[namespace]: {quux: 'bla'}}});
assert.equal(inst.t('quux'), 'bla');
assert.equal(inst.t('foo'), 'bar');
i18next.setOverrides(inst, {en: {[namespace]: {}}});
assert.equal(inst.t('quux'), 'quux');
assert.equal(inst.t('foo'), 'bar');
i18next.setOverrides(inst, {en: {[namespace]: {foo: 'hmm'}}});
assert.equal(inst.t('foo'), 'hmm');
i18next.setOverrides(inst, {en: {[namespace]: {quux: 'bla'}}});
assert.equal(inst.t('foo'), 'bar');
assert.equal(inst.t('quux'), 'bla');
i18next.setOverrides(inst, {});
assert.equal(inst.t('foo'), 'bar');
assert.equal(inst.t('quux'), 'quux');
});
}); });
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment