-
-
Notifications
You must be signed in to change notification settings - Fork 129
Integration Guide
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>
);
}
}
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);
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));
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.
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();
};