Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support new plural suffixes with JSON v4 format #252

Merged
merged 3 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ into resource files
{
"Loading...": "Wird geladen...", // uses existing translation
"Backslashes in single quote: ' \\ '": "__NOT_TRANSLATED__", // returns a custom string
"This is a multiline string": "this is a multiline string", // returns the key as the default value
"This is a multiline string": "this is a multiline string", // returns the key as the default value
"car": "car",
"car_blue": "One blue car",
"car_blue_plural": "{{count}} blue cars",
Expand Down Expand Up @@ -263,7 +263,7 @@ gulp.task('i18next', function() {
resource: {
// the source path is relative to current working directory
loadPath: 'assets/i18n/{{lng}}/{{ns}}.json',

// the destination path is relative to your `gulp.dest()` path
savePath: 'i18n/{{lng}}/{{ns}}.json'
}
Expand Down Expand Up @@ -307,7 +307,7 @@ const Parser = require('i18next-scanner').Parser;
const parser = new Parser(options);

const code = "i18next.t('key'); ...";
parser.parseFuncFromString(code);
parser.parseFuncFromString(code);

const jsx = '<Trans i18nKey="some.key">Default text</Trans>';
parser.parseTransFromString(jsx);
Expand Down Expand Up @@ -381,7 +381,7 @@ Get the value of a translation key or the whole i18n resource store
// Returns the whole i18n resource store
parser.get();

// Returns the resource store with the top-level keys sorted by alphabetical order
// Returns the resource store with the top-level keys sorted by alphabetical order
parser.get({ sort: true });

// Returns a value in fallback language (@see options.fallbackLng) with namespace and key
Expand Down Expand Up @@ -438,12 +438,12 @@ For example:
const customTransform = function _transform(file, enc, done) {
const parser = this.parser;
const content = fs.readFileSync(file.path, enc);

parser.parseFuncFromString(content, { list: ['i18n.t'] }, function(key) {
const defaultValue = '__L10N__';
parser.set(key, defaultValue);
});

done();
};
```
Expand All @@ -455,13 +455,13 @@ const hash = require('sha1');
const customTransform = function _transform(file, enc, done) {
const parser = this.parser;
const content = fs.readFileSync(file.path, enc);

parser.parseFuncFromString(content, { list: ['i18n._'] }, function(key) {
const value = key;
const defaultKey = hash(value);
parser.set(defaultKey, value);
});

done();
};
```
Expand All @@ -484,7 +484,7 @@ const customFlush = function _flush(done) {
// add your code
});
});

done();
};

Expand All @@ -500,6 +500,7 @@ Below are the configuration options with their default values:

```javascript
{
compatibilityJSON: 'v3', // One of: 'v1', 'v2', 'v3', 'v4
debug: false,
removeUnusedKeys: false,
sort: false,
Expand Down Expand Up @@ -553,6 +554,14 @@ Below are the configuration options with their default values:
}
```

#### compatibilityJSON

Type: `String` Default: `'v3'`

The `compatibilityJSON` version to use for plural suffixes.

See https://https://www.i18next.com/misc/json-format for details.

#### debug

Type: `Boolean` Default: `false`
Expand Down Expand Up @@ -724,7 +733,7 @@ Resource options:
```js
{ // Default
resource: {
// The path where resources get loaded from. Relative to current working directory.
// The path where resources get loaded from. Relative to current working directory.
loadPath: 'i18n/{{lng}}/{{ns}}.json',

// The path to store resources. Relative to the path specified by `gulp.dest(path)`.
Expand All @@ -745,7 +754,7 @@ Resource options:
```js
{ // Default
resource: {
// The path where resources get loaded from. Relative to current working directory.
// The path where resources get loaded from. Relative to current working directory.
loadPath: function(lng, ns) {
return 'i18n/'+lng+'/'+ns+'.json';
},
Expand Down Expand Up @@ -857,7 +866,7 @@ interpolation options

Type: `Object` Default: `{}`

This can be used to pass any additional information regarding the string.
This can be used to pass any additional information regarding the string.

#### allowDynamicKeys

Expand Down
1 change: 1 addition & 0 deletions examples/i18next-scanner.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
],
output: './',
options: {
compatibilityJSON: 'v3',
debug: true,
func: {
list: ['i18next.t', 'i18n.t'],
Expand Down
41 changes: 10 additions & 31 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ import flattenObjectKeys from './flatten-object-keys';
import nodesToString from './nodes-to-string';
import omitEmptyObject from './omit-empty-object';

i18next.init({
compatibilityJSON: 'v3',
});

const defaults = {
compatibilityJSON: 'v3', // JSON format

debug: false, // verbose logging

sort: false, // sort keys in alphabetical order
Expand Down Expand Up @@ -224,32 +222,6 @@ const normalizeOptions = (options) => {
return options;
};

// Get an array of plural suffixes for a given language.
// @param {string} lng The language.
// @param {string} pluralSeparator pluralSeparator, default '_'.
// @return {array} An array of plural suffixes.
const getPluralSuffixes = (lng, pluralSeparator = '_') => {
const rule = i18next.services.pluralResolver.getRule(lng);

if (!(rule && rule.numbers)) {
return []; // Return an empty array if lng is not supported
}

if (rule.numbers.length === 1) {
return [`${pluralSeparator}0`];
}

if (rule.numbers.length === 2) {
return ['', `${pluralSeparator}plural`];
}

const suffixes = rule.numbers.reduce((acc, n, i) => {
return acc.concat(`${pluralSeparator}${i}`);
}, []);

return suffixes;
};

/**
* Creates a new parser
* @constructor
Expand All @@ -272,14 +244,21 @@ class Parser {
...options
});

const i18nextInstance = i18next.createInstance();
i18nextInstance.init({
compatibilityJSON: this.options.compatibilityJSON,
pluralSeparator: this.options.pluralSeparator,
});

const lngs = this.options.lngs;
const namespaces = this.options.ns;

lngs.forEach((lng) => {
this.resStore[lng] = this.resStore[lng] || {};
this.resScan[lng] = this.resScan[lng] || {};

this.pluralSuffixes[lng] = ensureArray(getPluralSuffixes(lng, this.options.pluralSeparator));
this.pluralSuffixes[lng] = i18nextInstance.services.pluralResolver.getSuffixes(lng);

if (this.pluralSuffixes[lng].length === 0) {
this.log(`No plural rule found for: ${lng}`);
}
Expand Down
27 changes: 27 additions & 0 deletions test/parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,33 @@ describe('Plural', () => {
});
});

test('compatibilityJSON', () => {
const parser = new Parser({
compatibilityJSON: 'v4',
lngs: ['en'],
});
const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/plural.js'), 'utf-8');
parser.parseFuncFromString(content, { propsFilter: props => props });
expect(parser.get()).toEqual({
en: {
translation: {
'key_one': '',
'key_other': '',
'keyWithCount_one': '',
'keyWithCount_other': '',
'keyWithVariable_one': '',
'keyWithVariable_other': '',
'keyWithCountAndDefaultValues_one': '{{count}} item',
'keyWithCountAndDefaultValues_other': '{{count}} item',
'keyWithDefaultValueAndCount_one': '{{count}} item',
'keyWithDefaultValueAndCount_other': '{{count}} item',
'keyWithDefaultValueAndVariable_one': '{{count}} item',
'keyWithDefaultValueAndVariable_other': '{{count}} item',
}
}
});
});

test('User defined function', () => {
const parser = new Parser({
plural: (lng, ns, key, options) => {
Expand Down
Loading