diff --git a/README.md b/README.md
index f0ef401..5fe104f 100644
--- a/README.md
+++ b/README.md
@@ -219,6 +219,8 @@ static-i18n --attr-selector my-attr-t ...
}
}
```
+* `interpolationPrefix` (default: `{{`): Override the default interpolation prefix
+* `interpolationSuffix` (default: `}}`): Override the default interpolation suffix
* `i18n`: Object passed directly to [`i18next.init`](http://i18next.com/pages/doc_init.html). This allows you to override pretty much anything. Read [i18next](http://i18next.com/) doc for more info.
When using the CLI, `outputOverride` and `i18n` options are parsed as JSON.
diff --git a/lib/index.js b/lib/index.js
index 118b420..2962e23 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -38,6 +38,8 @@ const defaults = {
nsSeparator: ":",
encoding: 'utf8',
translateConditionalComments: false,
+ interpolationPrefix: '{{',
+ interpolationSuffix: '}}',
i18n: {
resGetPath: 'locales/__lng__.json',
setJqueryExt: false
@@ -105,6 +107,13 @@ function getOptions(baseOptions) {
if (_.isUndefined(baseOptions.outputDir)) {
options.outputDir = path.join(process.cwd(), 'i18n');
}
+
+ if (_.isUndefined(options.i18n.interpolation)){
+ options.i18n.interpolation = {}
+ options.i18n.interpolation.prefix = options.interpolationPrefix = _.escapeRegExp(options.interpolationPrefix);
+ options.i18n.interpolation.suffix = options.interpolationSuffix = _.escapeRegExp(options.interpolationSuffix);
+ }
+
return options;
}
@@ -155,7 +164,8 @@ function translateAttributes($elem, options, t) {
const attr = isData ? k : k.substring(0, k.length - options.attrSuffix.length);
let trans = t(v);
if (interpolate) {
- trans = v.replace(/{{([^{}]*)}}/g, function(aa, bb) {
+ const replaceRegex = new RegExp(`${options.interpolationPrefix}([^{}]*)${options.interpolationSuffix}`, 'g')
+ trans = v.replace(replaceRegex, function(aa, bb) {
return t(bb);
});
}
@@ -175,6 +185,8 @@ function translateAttributes($elem, options, t) {
function translateElem($, elem, options, t) {
let key, attr;
+ const replaceRegex = new RegExp(`${options.interpolationPrefix}([^{}]*)${options.interpolationSuffix}`, 'g')
+
const $elem = $(elem);
if (options.useAttr && (attr = /^\[(.*?)\]$/.exec(options.selector))) {
key = $elem.attr(attr[1]);
@@ -192,7 +204,7 @@ function translateElem($, elem, options, t) {
const interpolateAttr = getAttrFromSelector(options.interpolateSelector);
const interpolate = $elem.filter(options.interpolateSelector).length;
if (interpolate) {
- trans = trans.replace(/{{([^{}]*)}}/g, function(aa, bb) {
+ trans = trans.replace(replaceRegex, function(aa, bb) {
return t(bb);
});
}
@@ -201,7 +213,7 @@ function translateElem($, elem, options, t) {
}
if (options.allowHtml) {
if (interpolate) {
- $elem.html($elem.html().replace(/{{([^{}]*)}}/g, function(aa, bb) {
+ $elem.html($elem.html().replace(replaceRegex, function(aa, bb) {
return t(bb);
}));
} else {
diff --git a/package.json b/package.json
index 9b9a377..5d1a14a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "static-i18n",
- "version": "0.2.10",
+ "version": "0.2.11",
"description": "Utility to translate static HTML files.",
"main": "lib/index.js",
"bin": {
diff --git a/test/index-test.js b/test/index-test.js
index 3923ffb..88bb262 100644
--- a/test/index-test.js
+++ b/test/index-test.js
@@ -75,6 +75,40 @@ describe('processor', function () {
expect($('input').attr('data-attr-t-interpolate')).to.be(undefined);
});
+ it('should support custom prefix and suffix when translating attributes with interpolation', async function () {
+ options = _.merge({}, options, { locales: ['en', 'ja'], interpolationPrefix: '_{', interpolationSuffix: '}' });
+ const input =
+ '';
+ const results = await staticI18n.process(input, options);
+ let $ = cheerio.load(results.en);
+ expect($('input').attr('href')).to.be(
+ 'http://www.example.com/filename.html'
+ );
+ expect($('input').attr('data-attr-t-interpolate')).to.be(undefined);
+ $ = cheerio.load(results.ja);
+ expect($('input').attr('href')).to.be(
+ 'http://www.example.com/ja/filename.htm'
+ );
+ expect($('input').attr('data-attr-t-interpolate')).to.be(undefined);
+ });
+
+ it('should escape regex characters in prefix and suffix', async function () {
+ options = _.merge({}, options, { locales: ['en', 'ja'], interpolationPrefix: '${', interpolationSuffix: '}$' });
+ const input =
+ '';
+ const results = await staticI18n.process(input, options);
+ let $ = cheerio.load(results.en);
+ expect($('input').attr('href')).to.be(
+ 'http://www.example.com/filename.html'
+ );
+ expect($('input').attr('data-attr-t-interpolate')).to.be(undefined);
+ $ = cheerio.load(results.ja);
+ expect($('input').attr('href')).to.be(
+ 'http://www.example.com/ja/filename.htm'
+ );
+ expect($('input').attr('data-attr-t-interpolate')).to.be(undefined);
+ });
+
it('should remove interpolation related attributes', async function () {
options = _.merge({}, options, { locales: ['en'] });
@@ -145,12 +179,12 @@ describe('processor', function () {
describe('#processDir', function () {
it('should process all files', async function () {
- _.merge(options, { locales: ['en', 'ja'], exclude: ['ignored/'] });
+ _.merge(options, { locales: ['en', 'ja'], exclude: [`ignored${path.sep}`] });
const results = await staticI18n.processDir(basepath, options);
expect(results).to.only.have.keys([
'index.html',
'other.html',
- 'sub/index.html',
+ path.join('sub', 'index.html'),
]);
expect(results['index.html']).to.only.have.keys(['en', 'ja']);
expect(results['other.html']).to.only.have.keys(['en', 'ja']);