1

Just got started with i18n for translating my website in Node. I'm at a bit of a loss of how to translate text that is generated after the DOM has loaded and jade file rendered (like after a user clicks a button).

I understand that i18n is a server side module and my new text generated is on the client side.

I'm also running express, if that helps.

What I want to do is to be able to translate text that has been generated by javascript on the client side. Consider an arbitrary button:

INDEX.JADE
    form.feedback-r
        a#submitclientiddd.button.button-primary #{i18n.__('Reply')}
    // Other Jade Stuff Here
    script(src='javascripts/clientside.js', type='text/javascript')

CLIENT SIDE JS
    $("#posts").on("submit", "form.feedback-r", function(e) {
        actbutton.html("Sending").addClass("feedback").removeClass('send_reply').prop("disabled", true);
    });
... AJAX FUNCTION REQUEST AND ON SUCCESS ...
        actbutton.html("Reply").addClass("success-text").prop("disabled", false);

SERVER SIDE JS
    res.render('index', { title: 'Page Title', i18n: res});
  1. First button text rendered by jade through i18n with (i18n.__('Reply')) and translated properly
  2. User clicks on button
  3. Text is changed via jQuery to read "Sending", and after an AJAX request back to "Reply"
  4. The button text is no longer translated since it was dynamically generated

Is there a way to use i18n on the client side to solve this problem? In the most ideal case, I'd like to just do this on the client side, but it's not working:

actbutton.html(i18n.__('Reply'));
Michał
  • 868
  • 1
  • 10
  • 36

2 Answers2

0
  1. I suggest starting here: https://www.npmjs.com/package/i18n-express in this page you'll find a starting explanation with this package which I recommend.

  2. The JSON file should hold the translated key/value strings (no matter which level its on).

  3. Working solution:

What I want to do is to be able to translate text that has been generated by JavaScript on the client side.

In this case you'll need to manipulate existing data in the template(view), because i18 module runs on the server-side.

For example you can store the translated text later-to-inject to this very button inside a data-sent attribute like this:

//-INDEX.JADE
form.feedback-r
    a#submitclientiddd.button.button-primary(data-reply-text='#{i18n.__('Reply')}', data-sending-text='#{i18n.__('Sending')}') #{i18n.__('Reply')}

//-CLIENT SIDE JS
var sending_text = $('a#submitclientiddd').attr('data-sending-text');
$("#posts").on("submit", "form.feedback-r", function(e) {  actbutton.text(sending_text); });

//-AJAX FUNCTION REQUEST AND ON SUCCESS 
var reply_text = $('a#submitclientiddd').attr('data-reply-text');
actbutton.text(reply_text); //(back to reply text)
Nate Ben
  • 626
  • 9
  • 14
  • Hi Nate! Thanks for your help! I've updated my question to hopefully provide a clearer example of my problem. – Michał Feb 06 '17 at 14:16
  • Very interesting solution! The only issue here that I see is that I would not be able to translate "Sending" (as per example above) since it wouldn't be defined... Any way around that? – Michał Feb 06 '17 at 14:35
  • If i got it correctly, something like this should work for you: in JADE template: `` button(data-translated-en='#{t('buttons.sending')}')=t('buttons.hello') `` explain: #{ t('buttons.sending') } the t() function evaluate string from i18 locale file with #{} you include it in the template. – Nate Ben Feb 06 '17 at 14:43
  • I may not be phrasing the question right. Thats fine for the initial jade template, but what I'm interested is in adding the functionality after the template has rendered. What if I wanted to add a button that is added dynamically with Javascript after the DOM loads? I'm pretty sure I need to include some new javascript library... I've updated the question with some code so you can see at what stage I'm at. – Michał Feb 06 '17 at 16:17
0

I managed to solve this by installing browser-i18n to my public javascript folder (not via NPM), and then using the same functions client-side as with i18n on Node.

The only problem is that browser-i18n looks like it doesn't support ranged values, like: [0] Reply | [1,] Replies. i18n-for-browser may be a possible solution.

Michał
  • 868
  • 1
  • 10
  • 36