Search code examples
internationalizationexpresstemplate-enginepug

I18N with Express/Jade: Strings with embedded tags and interpolation


tl;dr: I am looking for an elegant method of doing internationalization in Jade templates. Essentially the problem boils down to that I have to do interpolation on strings in variables, instead of verbatim code.

Problem details:

In a monolingual Jade template I can just make an element with embedded tags and variables like so:

p Posted by 
  span.author= post.author
  | on
  span.date= post.author

to get something like

<p>Posted by <span style="author">The Author</span> on 
<span style="date">2012-03-08</span></p>

But when I want to internationalize this, I need a single string, since word order is not the same in every language. Also, I would like to hide html details from translators, and just give them a line like this:

Posted by #{author} on #{date}

Now when I pass the i18n-ed version of this string to the Jade template as i18n.posted_by_on, it won't do interpolation on it, so the best I can do is:

- var author = '<span class="author">$</span>'.replace('$',post.author); 
- var date = '<span class="date">$</span>'.replace('$',post.date);
- var header = i18n.posted_by_on
      .replace('#{author}',author)
      .replace('#{date}',date); 
p!= header

This mostly defeats the point of the nice Jade templating, as I have to do all the interpolation manually. Is there any method doing it more nicely, compactly, readable?


Solution

  • You probably found a solution by now (if so, please tell us what it is), but if you didn't, you might want to look at the i18next-node library. It supports variables, so you could do things like:

    // Localized resources
    {           
      'en-GB': {
        translation: { 
            space_temperature_is: 'Space temperature is __COUNT__ degrees Celsius.'
         }
       }
      'fr-FR': {
        translation: { 
            space_temperature_is: 'Température de l'espace est de __COUNT__ degrés Celsius.'
         }
       }
    };
    

    Then, in your jade template, you would do:

    // This translates to "Space temperature is 28 degrees Celsius."
    i18n.t('space_temperature_is', { COUNT: 28 });
    

    The library is really well documented, but, if you're in a hurry, here's an article that I found useful as a quick introduction.