9

I recently started to give a go to React js and im starting to like it.

There is one logic what i am stuck with.

My site is multi-language and i have problems rendering the strings.

So what i thought is to place a data-translate attribute to the id's or classes but still does not fit right.

This is just a basic example of my logic

React js

var counter =  document.getElementById('counter').getAttribute('data-translate');

var Timer = React.createClass({


  getInitialState: function() {
    return {secondsElapsed: 0};
  },
  tick: function() {
    this.setState({secondsElapsed: this.state.secondsElapsed + 1});
  },
  componentDidMount: function() {
    this.interval = setInterval(this.tick, 1000);
  },
  componentWillUnmount: function() {
    clearInterval(this.interval);
  },
  render: function() {
    return (
      <div className={this.translate}>{counter} {this.state.secondsElapsed}</div>
    );
  }
});



React.renderComponent(
    <Timer />,
    document.getElementById('counter')
  );

HTML

<div id="counter" data-translate="{{ trans('stream.counter') }}"></div>

So not the best idea.

Could someone give me a hint?

0

2 Answers 2

9

You want to convert your translation files into JSON and use a client side translation function.

For example, image you generated something like this:

var translations = {"en":{"stream":{"counter":"counter"}}};

You could then write trans like this:

function trans(key){
  var keys = key.split(".");
  var lang = navigator.language.split("-");
  return lang.concat(keys).reduce(function(o, k){
    var next = o[k];
    if (!next) {
      console.error('No translation found for ' + key, new Error().stack);
      return {};
    }
    else {
      return next;
    }
  }, translations);
}

And in your components, just use

<div>{trans('stream.counter')}</div>
Sign up to request clarification or add additional context in comments.

1 Comment

This works great... I needed to change if (next) to if(!next) though
1

An API like gettext will do what you need. During application initialisation, you'd set up a dictionary with source keys being the "fallback language" text, and the values in the destination language.

// Data source initialised once, could be embedded in the source from the server.
var TranslationDictionary = {
    "the ticks": "les tiques",
    ...
};

// In the component:
return <div>{gettext("the ticks")}</div>;

// Then the gettext utility to join them together:
function gettext(lookup) {
    var translation = TranslationDictionary[lookup];
    if (translation) {
        return translation;
    }
    else {
        console.log("Warning: missing translation for: " + lookup);
        return lookup;
    }
}

The gettext function is then very simple, and since the keys are the full text in the fallback language, the view code is still easy to read. Bonus points if you write a code analyser which looks for missing translations.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.