i18n Translation of Dynamically Added Text

2019-09-15 04:02发布

问题:

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

回答1:

  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)


回答2:

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.