Skip to content
Ricardo Almeida Silva edited this page Apr 1, 2016 · 4 revisions

React

An example of resource file:

{           
    "app": {
        "name": "My App"
    },
    "key": "__myVar__ are important"
}

Use i18next.t() in your React JSX code:

import i18next from 'i18next';
import React from 'react';

class App extends React.Component {
    render() {
        return (
            <div>
                <h1>{i18next.t('app.name')}</h1> // "My App"
                <p>{i18next.t('key', { myVar:'variables' })}</p> // "variables are important"
            </div>
        );
    }
}

Gettext Style I18n

First, you have to upgrade i18next to v2.1.0 at least to support the Key Based Fallback feature.

Here is an example of finding all occurrences of the _t() function in your code:

_t('This is text value');
_t("text");
_t('text');
_t("text", { count: 1 });
_t("text" + str); // skip run-time variables

The content can be parsed using the parser API:

parser.parseFuncFromString(content, options = {}, customHandler = null)

The code might look like this:

var Parser = require('i18next-scanner').Parser;

///
// You have to use i18next@^2.1.0, and set both nsSeparator and keySeparator to false
///
var parser = new Parser({
    nsSeparator: false,
    keySeparator: false
});

var content = fs.readFileSync('/path/to/app.js', 'utf-8');
parser.parseFuncFromString(content, { list: ['_t'] });

console.log(parser.getResourceStore());

Usage with Gulp:

var gulp = require('gulp');
var scanner = require('i18next-scanner');

var customTransform = function(file, enc, done) {
    var parser = this.parser;
    var content = fs.readFileSync(file.path, enc);

    parser.parseFuncFromString(content, { list: ['_t'] });

    done();
};

gulp.src(src)
    .pipe(scanner(options, customTransform))
    .pipe(dest);

Handlebars

Here is an example of what our template file might look like:

function helper

{{i18n 'bar'}}
{{i18n 'bar' defaultKey='foo'}}
{{i18n 'baz' defaultKey='namespace:foo'}}
{{i18n defaultKey='noval'}}
{{i18n 'Basic Example'}}
{{i18n '__first-name__ __last-name__' first-name=firstname last-name=lastname}}
{{i18n 'English' defaultKey='locale:language.en-US'}}
{{i18n defaultKey='loading'}}

block helper

{{#i18n}}Some text{{/i18n}}
{{#i18n this}}Description: {{description}}{{/i18n}}
{{#i18n this last-name=lastname}}{{firstname}} __last-name__{{/i18n}}

You can compile the template string into a Handlebars template function, and then render the template by passing a data object (a.k.a. context) into that function:

var source = fs.readFileSync('/path/to/your/handlebars-template.hbs'), 'utf-8');
var template = handlebars.compile(source);
var context = {
    'firstname':'Foo',
    'lastname':'Bar',
    'description': 'Foo Bar Test'
};
console.log(template(context));

Handlebars Helper

Use the Handlebars.registerHelper method to register the i18n helper:

var handlebars = require('handlebars');
var i18next = require('i18next');

var handlebarsHelper = function(context, options) {
    var defaultValue;

    if ((typeof context === 'object') && (typeof options === 'undefined')) {
        // {{i18n defaultKey='loading'}}
        options = context;
        context = undefined;
    }

    if ((typeof options === 'object') && (typeof options.fn === 'function')) {
        // {{#i18n}}<span>Some text</span>{{/i18n}}
        // {{#i18n this}}<p>Description: {{description}}</p>{{/i18n}}
        defaultValue = options.fn(context);
    } else if (typeof context === 'string') {
        // {{i18n 'Basic Example'}}
        // {{i18n '__first-name__ __last-name__' first-name=firstname last-name=lastname}}
        // {{i18n 'English' defaultKey='locale:language.en-US'}}
        defaultValue = context;
    }

    options = options || {};
    options.hash = options.hash || {};

    var opts = options.hash;
    opts.defaultValue = defaultValue;
    var defaultKey = options.hash.defaultKey;
    var result;

    if (typeof defaultKey === 'undefined') {
        result = i18next.t(defaultValue, opts);
    } else {
        result = i18next.t(defaultKey, opts);
    }

    return result;
};

handlebars.registerHelper('i18n', handlebarsHelper);

By default, Handlebars will escape the returned result by default. If you want to generate HTML, you have to return a new Handlebars.SafeString(result) like so:

var handlebars = require('handlebars');

handlebars.registerHelper('i18n', function() {
    var result = handlebarsHelper.apply(this, arguments);
    return new handlebars.SafeString(result);
});

In such a circumstance, you will want to manually escape parameters.

Example

The sample code might look like this:

var _ = require('lodash');
var hash = require('sha1');

var customTransform = function(file, enc, done) {
    var parser = this.parser;
    var extname = path.extname(file.path);
    var content = fs.readFileSync(file.path, enc);

    // function helper
    (function() {
        var results = content.match(/{{i18n\s+("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')?([^}]*)}}/gm) || [];
        _.each(results, function(result) {
            var key, value;
            var r = result.match(/{{i18n\s+("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')?([^}]*)}}/m) || [];

            if ( ! _.isUndefined(r[1])) {
                value = _.trim(r[1], '\'"');

                // Replace double backslash with single backslash
                value = value.replace(/\\\\/g, '\\');
                value = value.replace(/\\\'/, '\'');                              
            }

            var params = parser.parseHashArguments(r[2]);
            if (_.has(params, 'defaultKey')) {
                key = params['defaultKey'];
            }
                
            if (_.isUndefined(key) && _.isUndefined(value)) {
                return;
            }

            if (_.isUndefined(key)) {
                key = hash(value); // returns a hash value as its default key
            }

            parser.parseKey(key, value);
        });
    }());

    // block helper
    (function() {
        var results = content.match(/{{#i18n\s*([^}]*)}}((?:(?!{{\/i18n}})(?:.|\n))*){{\/i18n}}/gm) || [];
        _.each(results, function(result) {
            var key, value;
            var r = result.match(/{{#i18n\s*([^}]*)}}((?:(?!{{\/i18n}})(?:.|\n))*){{\/i18n}}/m) || [];

            if ( ! _.isUndefined(r[2])) {
                value = _.trim(r[2], '\'"');
            }

            if (_.isUndefined(value)) {
                return;
            }

            key = hash(value); // returns a hash value as its default key
            parser.parseKey(key, value);
        });
    }());

    done();
};
Clone this wiki locally