【发布时间】:2026-01-17 04:30:01
【问题描述】:
我有一个渲染 EJS 模板的方法,并通过将 i18next t 函数设置为数据对象的属性来传递 EJS 模板的 i18next.t 函数进行翻译:
const data = {
email: user.email,
id: user.id,
t: i18nT
};
数据对象被传入ejs.renderFile()。我可以让 EJS 模板中的翻译工作的唯一方法是当我从 i18next.init() 函数回调中将 i18nT 变量设置为 t 函数时。否则它会出现空白。我从控制台输出看到i18next实例的t函数i18nInstance与初始化i18next时回调设置的t函数不同。
function t() {
var _this$translator;
return this.translator && (_this$translator =
this.translator).translate.apply(_this$translator, arguments);
}
对比:
function () {
return _this4.t.apply(_this4, arguments);
}
为什么调用 i18next.createInstance() 得到的 i18nInstance 对象的 t 函数与回调中的不同?来自实例对象的那个在 EJS 模板渲染中不起作用。
完整的代码示例:
let i18nInstance: i18n;
let i18nT;
const i18nextInitOptions = {
backend: {
loadPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.json'),
addPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.missing.json')
},
debug: true,
fallbackLng: 'da',
preload: ['da', 'en', 'nl'],
returnEmptyString: false,
returnNull: false,
saveMissing: true
};
i18nInstance = await i18next
.createInstance();
await i18nInstance
.use(i18nextBackend)
.init(i18nextInitOptions, async function (error, t) {
if (error) {
console.log(error)
}
i18nT = t;
});
console.log("i18nT: " + i18nT)
/*
The console.log outputs below show that i18nT when set from the callback is different to the
i18nInstance.t.
i18nT: function () {
return _this4.t.apply(_this4, arguments);
}
*/
console.log("i18nInstance.t: " + i18nInstance.t)
/*
console output:
i18nInstance.t: function t() {
var _this$translator;
return this.translator && (_this$translator =
this.translator).translate.apply(_this$translator, arguments);
}
*/
const data1 = {
email: user.email,
id: user.id,
t: i18nT
};
// Calling htmlFromTemplate with data1 with t = i18nT the translation in the EJS template works.
html = await this.htmlFromTemplate('ejsTemplateName.ejs', data1);
const data2 = {
email: user.email,
id: user.id,
t: i18nextInstance.t
};
// Calling htmlFromTemplate with data2 with t = i18nextInstance.t the translation in the EJS is empty.
html = await this.htmlFromTemplate('ejsTemplateName.ejs', data2);
private htmlFromTemplate(templateName: string, data: Object): Promise<String> {
if (!templateName) return;
const htmlPath = path.join(__dirname, '../assets/mail-templates/' + templateName);
return new Promise((resolve, reject) => {
ejs.renderFile(htmlPath, data,(renderErr, str) => {
if (renderErr) {
appLogger.error('MAIL_RENDER: ' + renderErr, { templateName, data });
reject(renderErr);
} else resolve(str);
});
});
}
【问题讨论】: