Git Product home page Git Product logo

i18next-intervalplural-postprocessor's Introduction

i18next-intervalPlural-postProcessor

Introduction

Travis Coveralls npm version Bower David

This is a i18next postProcessor enabling interval based plurals.

Getting started

Source can be loaded via npm, bower or downloaded from this repo.

# npm package
$ npm install i18next-intervalplural-postprocessor

# bower
$ bower install i18next-intervalplural-postprocessor
  • If you don't use a module loader it will be added to window.i18nextIntervalPluralPostProcessor

Wiring up:

import i18next from 'i18next';
import intervalPlural from 'i18next-intervalplural-postprocessor';

i18next
  .use(intervalPlural)
  .init(i18nextOptions);

Usage sample

// given loaded resources
// translation: {
//    key1_one: '{{count}} item',
//    key1_other: '{{count}} items',
//    key1_interval: '(1)[one item];(2-7)[a few items];(7-inf)[a lot of items];',
//    key2_one: '{{count}} item',
//    key2_other: '{{count}} items',
//    key2_interval: '(1)[one item];(2-7)[a few items];'
// }

i18next.t('key1_interval', { postProcess: 'interval', count: 1 }); // -> one item
i18next.t('key1_interval', { postProcess: 'interval', count: 4 }); // -> a few items
i18next.t('key1_interval', { postProcess: 'interval', count: 100 }); // -> a lot of items

// if a interval is not specified i18next fallbacks to classic plural
i18next.t('key2_interval', { postProcess: 'interval', count: 1 }); // -> one item
i18next.t('key2_interval', { postProcess: 'interval', count: 4 }); // -> a few items
i18next.t('key2_interval', { postProcess: 'interval', count: 100 }); // -> 100 items

Setting own options

import i18next from 'i18next';
import intervalPlural from 'i18next-intervalplural-postprocessor';

intervalPlural.setOptions({
  // these are the defaults
  intervalSeparator: ';',
  intervalRegex: /\((\S*)\).*?\[((.|\n)*)\]/, // pre 3.0 /\((\S*)\).*{((.|\n)*)}/,
  intervalSuffix: '_interval'
});

i18next
  .use(intervalPlural)
  .init(i18nextOptions);

Gold Sponsors

i18next-intervalplural-postprocessor's People

Contributors

adrai avatar greenkeeperio-bot avatar jamuhl avatar msftenhanceprovenance avatar seleb avatar tsugami avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

i18next-intervalplural-postprocessor's Issues

intervalPlural.setOptions doesn't work

Hi all,

First of all, thank you for the great plugin! However, I was trying to set it up with a custom regular expression and ran into an issue. The setOptions function of the plugin doesn't work, as it's extending the options in the wrong order.

Line 36 of index.js:

  setOptions: function setOptions(options) {
    this.options = _extends({}, options, this.options);
  },

This means than the default options will always override the ones that were passed in.

Is there a specific reason why this happens? Otherwise, it should be:

this.options = _extends({}, this.options, options);

At the moment, it's possible to override the settings using intervalPlural.options =, but I'm not sure that is the intended behaviour.

Translation interval with the variable not working

🐛 Bug Report

Translation where the variable directly succeeds the { in the interval does not work.

To Reproduce

In the example below the name wont be replaced when the count is 1 but it will fallback to the plural version.

Translation:

  "hosts_interval": "(0){your hosts};(1){{{name}}};(2-inf){your hosts};",

Code:

  const hostsText = t('hosts_interval', {
    name: 'John',
    postProcess: 'interval',
    count: 1,
  });

Expected behavior

The variable should be parsed correctly and replaced.

Your Environment

  • i18next version: i.e. 19.8.4
  • i18next-intervalplural-postprocessor version: i.e. 2.0.2

Linebreak doesn't work

With this translation object

translation: {
  'LIKE_COUNT': '{{count}} person\nlikes this',
  'LIKE_COUNT_plural': '{{count}} people\nlike this',
  'LIKE_COUNT_interval': "(0){No one\nlikes this};"
}

And using

t('LIKE_COUNT_interval', {postProcess: 'interval', count: 0})}

It falls back to the plural rule. Also I had to guess what was failing by trial and error, it would be nice to have some log by i18next-intervalPlural-postProcessor when it can't parse the translation.

Doesn't fallback to classic plural

Given resources

"upload": {
  "files": "{{count}} файл был загружен",
  "files_plural": "{{count}} файлов было загружено",
  "files_interval": "(2-4){ {{count}} файлa было загружено};"
}

Invoke t like this:

const { count } = this.state;
...
t('upload.files_interval', { postProcess: 'interval', count })

Works fine for 2-4. But get 5 файл был загружен instead of 5 файлов было загружено

Regex Expression does not handle whitespace characters

The current regex - /^\((\S*)\){(.*)}$/

Will match each of the following statements twice when the string segments are split by ;

(0){zero};(1){single};
(a){zero};(Z){single};

However after splitting the following statements by interval, it will not match:

(0) {zero};(1) {single};
(0) {zero}; (1) {single};

I might recommend a match which catches whitespaces or warn users when with an exception.

Plural fallback with namespace fails

Currently using Locize and i18next. It seems like there is a problem with using namespaces that are not under the common namespace. The fallback to key2_plural never occurs as described in the documentation.

[FAIL]

		// if a interval is not specified i18next fallbacks to classic plural
		const x1 = t('foo:key2_interval', { postProcess: 'interval', count: 1 }); // -> one item
		const x2 = t('foo:key2_interval', { postProcess: 'interval', count: 4 }); // -> a few items
		const x3 = t('foo:key2_interval', { postProcess: 'interval', count: 100 }); // -> 100 items

[FAIL]

		// if a interval is not specified i18next fallbacks to classic plural
		const x1 = t('key2_interval', { ns:'foo', postProcess: 'interval', count: 1 }); // -> one item
		const x2 = t('key2_interval', { ns:'foo', postProcess: 'interval', count: 4 }); // -> a few items
		const x3 = t('key2_interval', { ns:'foo', postProcess: 'interval', count: 100 }); // -> 100 items

[PASS]

		// if a interval is not specified i18next fallbacks to classic plural
		const x1 = t('key2_interval', { postProcess: 'interval', count: 1 }); // -> one item
		const x2 = t('key2_interval', { postProcess: 'interval', count: 4 }); // -> a few items
		const x3 = t('key2_interval', { postProcess: 'interval', count: 100 }); // -> 100 items

interval Plural not working properly.

first great plugin.
1st ) I belive the Documentation needs to be updated.
i18next.use(intervalPlural) does not work, i get error not found. when i do i18next.use(i18nextIntervalPluralPostProcessor) i do not get an error.

  1. when i try to do a postprocess i get an error in the console log.
    here is my code

i18next 3.3.1
i18next-intervalPlural-postProcessor 0.2.3

i init like this

i18next
.use(i18nextBrowserLanguageDetector)
.use(i18nextXHRBackend)
.use(Cache)
.use(i18nextIntervalPluralPostProcessor)
.init(i18nextoptions, function (err, t) {
var options = $().jqueryI18nextOptions;
//init jquery-i18next
jqueryI18next.init(i18next, $,options);
......
.....
}

in my JSON file i have something like this
"validation": {
"progComplete" : "The $t(label.Plan) is empty.",
"progComplete_plural" : "Great, the $t(label.Plan) is complete.",
"progComplete_interval" : "(1-99){The Plan is incomplete, {{count}} error(s) detected, please go back and validate the Plan.};(99-inf){"test"})",
...
}

now in my JS file i call it like in the documentation

var progWrkMsg = $.t("validation.progComplete", {postProcess: 'interval', count: 2});

and the error in console log is like this:

i18next::translator: missingKey en translation validation.progComplete validation.progComplete.

now if don't call : .use(i18nextIntervalPluralPostProcessor) or in my JS i do not include "postprocessor" like this : var progWrkMsg = $.t("validation.progComplete", {count: 2});

i do not get an error and get the plural of the key : "Great, the Plan is comnplete."

Thank you

How should Arabic numeric ranges with numeric count be supported?

I recently tried using Locize.io with Gengo. I seem to have run into a limitation with the I18Next ecosystem.

**Arabic Intervals**

(0){دقيقة};
(1){دقيقة};
(2){دقيقتان};
(3-11){{{count}} دقائق};
(11-Inf){{{count}} دقيقة};

**English Intervals**

(0){0 minutes};
(1){1 minute};
(2-Inf){{{count}} minutes};

Is it expected that I expand English intervals in an unnatural way?

**English Intervals**

(0){0 minutes};
(1){1 minute};
(2){2 minutes};
(3-11){{{count}} minutes};
(11-Inf){{{count}} minutes};

I'm not too concerned with the extension of the English intervals above, but I am curious about whether or not this becomes problematic if there is a language that counts intervals 2-100 differently than Arabic when I am using English as my reference language.

Negative count and negative infinity

Is it possible to catch negative values?
Preferably from negative infinity to zero i.e -inf -> 0

I've tried:
(-inf-0){Lowest text to display}
(-1000-0){Lowest text to display}
but they don't seem to catch.

using `postProcess: 'interval'` in `i18next.init` fails

🐛 Bug Report

I didn't want to have to specify {postProcess: 'interval'} every time I wanted to use the interval post-processing, so I passed it to the i18next.init options instead and this caused translations without any options to fail at this line:

const index = newOptions.postProcess.indexOf('interval'); // <-- Not supported in <IE9

To Reproduce

i18next.init({
  postProcess: 'interval',
  ...
})
// ...
i18next.t("some-key") // Fails because it has no postProcess option

Expected behavior

The examples show postProcess: 'interval' being passed to every translation that wants to use it, so it seems to be intended behavior that this would fail, but it really shouldn't. Having to pass that option for every interval is annoying and makes the code more complicated. It already has the _interval suffix in the key, so why do we need this option? Else, why bother with the suffix? Seems like if the key has the _interval suffix it should just post process with this plugin, or this plugin should try to post process everything and check if the entry has interval post processing and handle it if so.

Just something so postProcess: 'interval' doesn't have to be passed every time, or allow postProcess: 'interval' to be specified in i18next.init and not fail on keys without options or _interval suffixes.

i18next.init({
  postProcess: 'interval',
  // ...
})
// ...
i18next.t("some-key") // Works!
// ...
i18next.t("other-key_interval", {count: 3}) // Works and handles intervals!

Your Environment

Don't think it really matters, seems like it's just a flaw in the coding but...

  • runtime version: electron 13, node 14
  • i18next version: 20.3.4
  • os: Windows

Typescript check error after upgrade to 2.0.0 or 2.0.1

🐛 Bug Report

After upgrade to version 2.0.0 or 2.0.1 of i18next-intervalplural-postprocessor there is an typescript error check in file https://github.com/i18next/i18next-intervalPlural-postProcessor/blob/master/index.d.ts, row 9 -> Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier.

To Reproduce

It is about this code shown below (file index.d.ts). To reproduce this error just install i18next-intervalplural-postprocessor dependecy and make sure you have "skipLibCheck": false in your tsconfig.json file.

const intervalPlural: PostProcessorModule & {
	name: 'interval';
	type: 'postProcessor';
	options: IntervalPluralOptions;
	setOptions: (options: Partial<IntervalPluralOptions>) => void;
};

Expected behavior

There should be no errors on typescript check.
Maybe this fix below should work (I am not sure if it is enough).

export const intervalPlural: PostProcessorModule & {
	name: 'interval';
	type: 'postProcessor';
	options: IntervalPluralOptions;
	setOptions: (options: Partial<IntervalPluralOptions>) => void;
};

Environment

  • node version: 12.18.0
  • npm version: 6.14.5
  • browser: Chrome v 83.0.4103.116
  • i18next version: 19.5.4
  • i18next-intervalplural-postprocessor version: 2.0.1
  • typescript version: 3.9.6
  • os: Win 10

Support for enumeration?

Is there any change to support enumeration?

{
  "day_interval": "(1, 21, 31, 41, 51){day};"
}

Maybe even support mix of enumeration + intervals

{
  "day_interval": "(1, 21, 22-30, 31, 41, 51-99){day};"
}

Combine with context

I'm using i18next and there seems to be an issue with combining this post processor with contexts.

For example, given the following translation strings:

{
  "joins": "joins",
  "joins_plural": "join",
  "joins_interval": "(0)nobody joins",
  "joins_past": "joined",
  "joins_past_plural": "joined",
  "joins_past_interval": "(0)nobody joined",
}

t("joins_interval", {count: 1, context: "past", postProcess: "interval"}) returns joined,
but t("joins_interval", {count: 0, context: "past", postProcess: "interval"}) returns nobody joins.

I would expect it to return nobody joined instead.

Am I missing something here?

Interpolation in an interval

Is it possible to interpolate within an interval?
E.g:

"my_interval": "(1){A {{names[0]}} order is not yet seen};(2){{{names[0]}} and {{names[1]}} orders are not yet seen};(3-inf){{{names[0]}}, {{names[1]}} and other orders are not yet seen};",

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.