express3-handlebars and 18next-node - internationalisation based on page?

送分小仙女□ 提交于 2020-01-15 05:00:12

问题


my first question here - please go easy. I'm using express, express3-handlebars and i18next-node with node.js

The plan is to work with a different translation namespace depending on which view (i.e. which handlebars file) is currently being served. So if we're looking at the page called ie(.hbs), i18next will look in the namespace called ie(.json) for the relevant language. This makes organisation and coordination of translations easier.

This is how I'm currently doing it: first I send the current page into the handlebars template for rendering (even this seems unnecessary - handlebars doesn't automatically expose which file it's rendering?):

res.render( url_base_path, { layout: ("sub"), title: title, currentpage: url_base_path } );

and then I access the variable "greeting" to be translated in the namespace of the current page like so {{t "greeting" page=currentpage }} - the annoying thing is that there are 10's of these variables on each page. Don't Repeat Yourself, anybody?

't' is defined in the express3-handlebars create() function, like so, helpers: { t: t }

and the translate function looks like this

var t = function (i18next_key, options) {
  var page, result;
  page = options.hash.page;
  result = i18next.t(page + ":" + i18next_key);
  return new hbs.handlebars.SafeString(result);
};

for the sake of full disclosure, this is what my (english) namespace file for the current page looks like

{
    "greeting": "Hello, it appears you're using Internet Explorer, an outdated web browser."
}

this works, but it seems like there should be a much simpler solution.

what i really want is to be able to just type {{t "greeting"}} into the handlebars template to achieve the same result. is this possible without overriding core handlebars functionality?

here is the i18next docs page http://i18next.com/pages/doc_features.html


回答1:


I've answered my own question - it turned out easier than I expected.

You can access the handlebars instance in my Handlebars translate helper (duh?), so in the helper: renderer = this (for clarity), then you can just access renderer.currentpage to get the name of the required namespace. Note, you still have to send currentpage in the render function (on res.render()), but I'm ok with that side of it.

I've done it like this (it's probably pretty slow like this at the moment, but it works exactly how I want it to):

  // Set namespace for translation
  options.ns = options.ns || bestNamespaceFor( i18n_key );

  result = i18n.t(i18n_key, options);
  return new hbs.handlebars.SafeString(result);

  function bestNamespaceFor( i18n_key ){
    if ( i18n.exists(i18n_key, { ns: renderer.currentpage }) ) return renderer.currentpage;
    if ( i18n.exists(i18n_key, { ns: renderer.layout }) ) return renderer.layout;
    if ( i18n.exists(i18n_key, { ns: "common" }) ) return "common";

Works perfectly with {{t "my translation key" }} and gets the right namespace no matter where I use it.



来源:https://stackoverflow.com/questions/20492766/express3-handlebars-and-18next-node-internationalisation-based-on-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!