【问题标题】:nodejs i18n __ is not a function issue with ejs, expressnodejs i18n __ 不是 ejs 的功能问题,表达
【发布时间】:2025-12-01 02:05:02
【问题描述】:

我想在我的 express (nodejs) 中实现多语言 但是我不明白为什么我的 ejs 不理解“__”下划线。

app.js

var i18n = require('./i18n');
app.use(i18n);

i18n.js

var i18n = require('i18n');

i18n.configure({
  locales:['fr', 'en'], 
  directory: __dirname + '/locales', 
  defaultLocale: 'en',
  cookie: 'lang'
});

module.exports = function(req, res, next) {
  i18n.init(req, res);
  res.locals.__ = res.__;
  var current_locale = i18n.getLocale();
  return next();
};

路由器.js

console.log(res.__('hello'));    // print ok
console.log(res.__('helloWithHTML')); // print ok

req.app.render('index', context, function(err, html) {
  res.writeHead('200', {'Content-Type':'text/html;charset=utf8'});  
  res.end(html);
});

/locales/en.json

{
  "hello": "Hello.",
  "helloWithHTML": "helloWithHTML."
}

index.ejs

<%= __("hello")%>

我收到了一条错误消息:

__ is not defined at eval (eval at compile (/home/nodejs/node_modules/ejs/lib/ejs.js:618:12), :41:7) at returnedFn 

但是我可以看到来自路由器的日志消息:

console.log(res.__('hello'));  // print out Hello
console.log(res.__('helloWithHTML')); // print out helloWithHTML

它工作正常,我可以看到 hellohelloWithHTML 值。

但是ejs 根本无法识别i18n 变量。

如何解决我的问题?

【问题讨论】:

  • 对我来说,看起来你的中间件不是针刺的。可以改写成module.export = i18n,然后在app.js里面写app.use(i18n.init);,就是为了简化,不知道现在的代码哪里出了问题。
  • @Starke 如果我放 app.use(i18n.init) 是相同的结果 :( 我需要弄清楚为什么这个问题会发生在我身上。奇怪的是 console.log(res.__('hello ')) 工作正常,所以我认为它与 ejs 或其他任何东西有关..
  • 是的,我也这么认为,req.app.render('index') 对我来说有点奇怪,通常它只是 res.render('index');
  • 我通常用中间件渲染。我还将我的应用设置为这样 app.set('view engine', 'ejs');

标签: node.js express internationalization underscore.js ejs


【解决方案1】:

来自文档:

一般来说,i18n 必须附加到响应对象上,才能在您的模板和方法中访问它的公共 api。从 0.4.0 开始,i18n 尝试在内部通过 i18n.init 执行此操作,就像您在 app.configure 中自己执行此操作一样

所以,您可以使用的最简单的方法是:

// i18nHelper.js file <-- you may want to rename the file so it's different from node_modules file
var i18n = require('i18n');

i18n.configure({
  locales:['fr', 'en'], 
  directory: __dirname + '/locales', 
  defaultLocale: 'en',
  cookie: 'lang'
});
module.export = i18n

// app.js
const i18n = require('./i18nHelper.js');
app.use(i18n.init);

或者如果你真的想绑定(自己):

// somei18n.js
module.exports = function(req, res, next) {
  res.locals.__ = i18n.__;
  return next();
};

// app.js
const i18nHelper = require('./somei18n.js')
app.use(i18nHelper);

app.get('/somepath', (req, res) => {
  res.render('index');
})

【讨论】:

  • 谢谢,但如果我直接声明 module.export = i18n,我只会看到有关“TypeError:app.use() 需要中间件函数”的错误消息,所以我必须编写 app.use(function ( req, res, next) { i18n.init(req, res); next(); });
  • 不直接,我更新了答案以反映您的示例
  • 终于解决了我的问题。我将字符集从 ms949 更改为 utf-8 en.json, fr.json 然后结果很好。所以我假设 i18n 敏感地与语言环境文件相关。无论如何,我的问题就消失了。非常感谢:)
【解决方案2】:

这是我的解决方案。

i18n.js

var i18n = require('i18n');

i18n.configure({
  locales: ['zh_CN', 'en'],
  directory: __dirname+'/locales'
});

module.exports = function(req, res, next) {
  let {lang} = req.query;
  i18n.init(req, res);
  lang = lang ? lang : 'zh_CN';
  i18n.setLocale(req, lang);
  return next();
};

其他文件和你一样。

希望对您有所帮助。

【讨论】: