[REF] web: slightly improve translation system

Before this commit, "lazy translated" strings were implemented as
objects with a toString function. This is simple, but does not emulate
very well the real behaviour of a string.

In this commit, we create a LazyTranslatedSTring class which subclass
the String class, so all string methods will work as expected.

We also expose the _t function here, to make it more convenient for some
code to access the translations instead of depending on the presence of
an environment.
This commit is contained in:
Géry Debongnie
2021-06-24 09:40:10 +00:00
committed by Lucas Perais (lpe)
parent 27538bca03
commit d4bbadd699
4 changed files with 47 additions and 8 deletions
+2 -2
View File
@@ -3,7 +3,7 @@
import { memoize } from "../utils/functions";
import { sprintf } from "../utils/strings";
import { localization } from "./localization";
import { _lt } from "./translation";
import { _t } from "./translation";
const { DateTime } = luxon;
@@ -276,7 +276,7 @@ export function parseDateTime(value, options = {}) {
}
if (!result) {
throw new Error(sprintf(_lt("'%s' is not a correct date or datetime").toString(), value));
throw new Error(sprintf(_t("'%s' is not a correct date or datetime"), value));
}
result = result.toUTC();
@@ -4,7 +4,7 @@ import { browser } from "../browser/browser";
import { registry } from "../registry";
import { strftimeToLuxonFormat } from "./dates";
import { localization } from "./localization";
import { translatedTerms } from "./translation";
import { translatedTerms, _t } from "./translation";
export const localizationService = {
dependencies: ["user"],
@@ -33,9 +33,6 @@ export const localizationService = {
}
Object.setPrototypeOf(translatedTerms, terms);
function _t(str) {
return terms[str] || str;
}
env._t = _t;
env.qweb.translateFn = _t;
const dateFormat = strftimeToLuxonFormat(userLocalization.date_format);
+26 -1
View File
@@ -2,6 +2,31 @@
export const translatedTerms = {};
/**
* Translate a term, or return the term if no translation can be found.
*
* Note that it translates eagerly, which means that if the translations have
* not been loaded yet, it will return the untranslated term. If it cannot be
* guaranteed that translations are ready, one should use the _lt function
* instead (see below)
*
* @param {string} term
* @returns {string}
*/
export function _t(term) {
return translatedTerms[term] || term;
}
class LazyTranslatedString extends String {
valueOf() {
const str = super.valueOf();
return _t(str);
}
toString() {
return this.valueOf();
}
}
/**
* Lazy translation function, only performs the translation when actually
* printed (e.g. inserted into a template).
@@ -12,7 +37,7 @@ export const translatedTerms = {};
* @returns {{toString: () => string}}
*/
export function _lt(str) {
return { toString: () => translatedTerms[str] || str };
return new LazyTranslatedString(str);
}
/*
@@ -1,6 +1,6 @@
/** @odoo-module **/
import { translatedTerms } from "@web/core/l10n/translation";
import { translatedTerms, _lt } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { patch, unpatch } from "@web/core/utils/patch";
import { makeTestEnv } from "../../helpers/mock_env";
@@ -27,6 +27,23 @@ QUnit.test("can translate a text node", async (assert) => {
unpatch(translatedTerms, "add translations");
});
QUnit.test("can lazy translate", async (assert) => {
assert.expect(3);
TestComponent.template = owl.tags.xml`<div><t t-esc="constructor.someLazyText" /></div>`;
TestComponent.someLazyText = _lt("Hello");
assert.strictEqual(TestComponent.someLazyText.toString(), "Hello");
assert.strictEqual(TestComponent.someLazyText.valueOf(), "Hello");
serviceRegistry.add("localization", makeFakeLocalizationService());
const env = await makeTestEnv();
patch(translatedTerms, "add translations", terms);
const target = getFixture();
await mount(TestComponent, { env, target });
assert.strictEqual(target.innerText, "Bonjour");
unpatch(translatedTerms, "add translations");
});
QUnit.test("_t is in env", async (assert) => {
assert.expect(1);
TestComponent.template = owl.tags.xml`<div><t t-esc="env._t('Hello')"/></div>`;