Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs i18n __ is not a function issue with ejs, express

I want to implement multi-language in my express (nodejs) However I cannot understand why my ejs do not understand "__" underscore.

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();
};

router.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")%>

I got an error message for this:

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

However I can see the log message from router:

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

It works fine, I can see both hello and helloWithHTML values.

But ejs do not recognize i18n variable at all.

How can I resolve my issue?

like image 671
Richard Avatar asked Oct 19 '25 09:10

Richard


1 Answers

From docs:

In general i18n has to be attached to the response object to let it's public api get accessible in your templates and methods. As of 0.4.0 i18n tries to do so internally via i18n.init, as if you were doing it in app.configure on your own

So, the simplest way you could use is:

// 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);

Or if you really want to bind (on your own):

// 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');
})
like image 129
1565986223 Avatar answered Oct 22 '25 01:10

1565986223



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!