i18next-parser
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -18,3 +18,3 @@ #!/usr/bin/env node | ||
program | ||
.version('0.2.0') | ||
.version('0.3.0') | ||
.option( '-r, --recursive' , 'Parse sub directories' ) | ||
@@ -21,0 +21,0 @@ .option( '-p, --parser <string>' , 'A custom regex to use to parse your code' ) |
@@ -5,3 +5,3 @@ { | ||
"name": "i18next-parser", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"bin": { | ||
@@ -8,0 +8,0 @@ "i18next": "./bin/cli.js" |
@@ -14,2 +14,3 @@ # i18next Parser | ||
- Restore keys from the `_old` file if the one in the translation file is empty. | ||
- Handles context keys of the form `key_context` | ||
- Handles plural keys of the form `key_plural` and `key_plural_0` | ||
@@ -66,3 +67,3 @@ - Is a stream transform (so it works with gulp) | ||
- **output**: Where to write the locale files. Defaults to `locales` | ||
- **output**: Where to write the locale files (relative to the base). Defaults to `locales` | ||
- **functions**: An array of functions names to parse. Defaults to `['t']` | ||
@@ -76,5 +77,29 @@ - **namespace**: Default namespace used in your i18next config. Defaults to `translation` | ||
### Note on paths (why your translations are not saved) | ||
**Events** | ||
The way gulp works, it take a `src()`, applies some transformations to the files matched and then render the transformation using the `dest()` command to a path of your choice. With `i18next-parser`, the `src()` takes the path to the files to parse and the `dest()` takes the path where you want the catalogs of translation keys. | ||
The problem is that the `i18next()` transform doesn't know about the path you specify in `dest()`. So it doesn't know where the catalogs are. So it can't merge the result of the parsing with the existing catalogs you may have there. | ||
``` | ||
gulp.src('app/**') | ||
.pipe(i18next()) | ||
.pipe(gulp.dest('custom/path')); | ||
``` | ||
If you consider the code above, any file that match the `app/**` pattern will have of base set to `app/`. *As per the vinyl-fs [documentation](https://github.com/wearefractal/vinyl-fs#srcglobs-opt) (which powers gulp), the base is the folder relative to the cwd and defaults is where the glob begins.* | ||
Bare with me, the `output` option isn't defined, it defaults to `locales`. So the `i18next()` transform will look for files in the `app/locales` directory (the base plus the output directory). But in reality they are located in `custom/path`. So for the `i18next-parser` to find your catalogs, you need the `output` option: | ||
``` | ||
gulp.src('app/**') | ||
.pipe(i18next({output: '../custom/path'})) | ||
.pipe(gulp.dest('custom/path')); | ||
``` | ||
The `output` option is relative to the base. In our case, we have `app/` as a base and we want `custom/path`. So the `output` option must be `../custom/path`. | ||
### Events | ||
The transform emit a `reading` event for each file it parses: | ||
@@ -81,0 +106,0 @@ |
@@ -47,6 +47,14 @@ // Takes a `path` of the form 'foo.bar' and | ||
else { | ||
// support for plural in keys | ||
pluralMatch = /_plural(_\d+)?$/.test( key ); | ||
singularKey = key.replace( /_plural(_\d+)?$/, '' ); | ||
if ( pluralMatch && target[singularKey] !== undefined ) { | ||
// support for context in keys | ||
contextMatch = /_([^_]+)?$/.test( singularKey ); | ||
rawKey = singularKey.replace( /_([^_]+)?$/, '' ); | ||
if ( | ||
( contextMatch && target[rawKey] !== undefined ) || | ||
( pluralMatch && target[singularKey] !== undefined ) | ||
) { | ||
target[key] = source[key]; | ||
@@ -53,0 +61,0 @@ } |
@@ -1,2 +0,2 @@ | ||
describe('i18next-parser', function () { | ||
describe('parser', function () { | ||
it('parses globally on multiple lines', function (done) { | ||
@@ -42,2 +42,47 @@ var result; | ||
}); | ||
it('parses jade templates', function (done) { | ||
var result; | ||
var i18nextParser = Parser(); | ||
var fakeFile = new File({ | ||
contents: fs.readFileSync( path.resolve(__dirname, 'templating/jade.jade') ) | ||
}); | ||
i18nextParser.on('data', function (file) { | ||
if ( file.relative === 'en/translation.json' ) { | ||
result = JSON.parse( file.contents ); | ||
} | ||
}); | ||
i18nextParser.on('end', function (file) { | ||
assert.deepEqual( result, { first: '' } ); | ||
done(); | ||
}); | ||
i18nextParser.end(fakeFile); | ||
}); | ||
it('parses handlebars templates', function (done) { | ||
var result; | ||
var i18nextParser = Parser(); | ||
var fakeFile = new File({ | ||
contents: fs.readFileSync( path.resolve(__dirname, 'templating/handlebars.hbs') ) | ||
}); | ||
i18nextParser.on('data', function (file) { | ||
if ( file.relative === 'en/translation.json' ) { | ||
result = JSON.parse( file.contents ); | ||
} | ||
}); | ||
i18nextParser.on('end', function (file) { | ||
assert.deepEqual( result, { first: '' } ); | ||
done(); | ||
}); | ||
i18nextParser.end(fakeFile); | ||
}); | ||
it('creates two files per namespace and per locale', function (done) { | ||
var results = []; | ||
@@ -81,7 +126,7 @@ var i18nextParser = Parser({ | ||
base: __dirname, | ||
contents: new Buffer("asd t('test3?first') t('test3?second-third')") | ||
contents: new Buffer("asd t('test_separators?first') t('test_separators?second-third')") | ||
}); | ||
i18nextParser.on('data', function (file) { | ||
if ( file.relative === 'en/test3.json' ) { | ||
if ( file.relative === 'en/test_separators.json' ) { | ||
result = JSON.parse( file.contents ); | ||
@@ -116,7 +161,7 @@ } | ||
base: __dirname, | ||
contents: new Buffer("asd t('test1:first') t('test1:second')") | ||
contents: new Buffer("asd t('test_merge:first') t('test_merge:second')") | ||
}); | ||
i18nextParser.on('data', function (file) { | ||
if ( file.relative === 'en/test1.json' ) { | ||
if ( file.relative === 'en/test_merge.json' ) { | ||
result = JSON.parse( file.contents ); | ||
@@ -133,2 +178,28 @@ } | ||
it('retrieves context values in existing file', function (done) { | ||
var i18nextParser = Parser(); | ||
var fakeFile = new File({ | ||
base: __dirname, | ||
contents: new Buffer("asd t('test_context:first')") | ||
}); | ||
var expectedResult = { | ||
first: 'first', | ||
first_context1: 'first context1', | ||
first_context2: '' | ||
}; | ||
i18nextParser.on('data', function (file) { | ||
if ( file.relative === 'en/test_context.json' ) { | ||
result = JSON.parse( file.contents ); | ||
} | ||
}); | ||
i18nextParser.once('end', function (file) { | ||
assert.deepEqual( result, expectedResult ); | ||
done(); | ||
}); | ||
i18nextParser.end(fakeFile); | ||
}); | ||
it('retrieves plural values in existing file', function (done) { | ||
@@ -138,3 +209,3 @@ var i18nextParser = Parser(); | ||
base: __dirname, | ||
contents: new Buffer("asd t('test2:first') t('test2:second')") | ||
contents: new Buffer("asd t('test_plural:first') t('test_plural:second')") | ||
}); | ||
@@ -151,3 +222,3 @@ | ||
i18nextParser.on('data', function (file) { | ||
if ( file.relative === 'en/test2.json' ) { | ||
if ( file.relative === 'en/test_plural.json' ) { | ||
result = JSON.parse( file.contents ); | ||
@@ -165,2 +236,29 @@ } | ||
it('retrieves plural and context values in existing file', function (done) { | ||
var i18nextParser = Parser(); | ||
var fakeFile = new File({ | ||
base: __dirname, | ||
contents: new Buffer("asd t('test_context_plural:first')") | ||
}); | ||
var expectedResult = { | ||
first: 'first', | ||
first_context1_plural: 'first context1 plural', | ||
first_context2_plural_2: 'first context2 plural 2' | ||
}; | ||
i18nextParser.on('data', function (file) { | ||
if ( file.relative === 'en/test_context_plural.json' ) { | ||
result = JSON.parse( file.contents ); | ||
} | ||
}); | ||
i18nextParser.once('end', function (file) { | ||
assert.deepEqual( result, expectedResult ); | ||
done(); | ||
}); | ||
i18nextParser.end(fakeFile); | ||
}); | ||
it('removes any trailing [bla] in the key', function (done) { | ||
@@ -167,0 +265,0 @@ var result; |
var fs = require('fs'); | ||
var path = require('path'); | ||
var assert = require('assert'); | ||
@@ -3,0 +4,0 @@ var File = require('vinyl'); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
82013
17
789
254