babel-plugin-i18next-extract icon indicating copy to clipboard operation
babel-plugin-i18next-extract copied to clipboard

Plurals with "discardOldKeys" true / general plural syntax

Open aaronfg opened this issue 4 years ago • 8 comments

Describe the bug

There seems to be no way to have the extraction accept a default value for the plural of a word.

How to reproduce

Trying to see how pluralization works with the extraction and also providing a defaultValue.

Based on the i18next docs, passing in "{count: x}" to the options object will let i18next look for the "key**_plural**" key, yes?

so given this code:

const test = t('TestKey', { count: 1, defaultValue: 'Test' });

the extracted string looks like this:

{
 "TestKey": "Test",
 "TestKey_plural": ""
}

How am I supposed to pass in what the default plural is?

I tried this to see what would happen:

const test = t('TestKey', { count: 1, defaultValue: 'Test' });
const tests = t('TestKey', { count: 2, defaultValue: 'Tests' });

But the extracted strings just overwrote the initial one and the extracted strings end up like this:

{
 "TestKey": "Tests",
 "TestKey_plural": ""
}

If I had the "TestKey" and "TestKey_plural" already in the file, then the code should work. But this plugin is for extracting/generating those keys/values in the file for me automatically. I'm just trying to figure out what the syntax is for what I'm describing.

What am I missing?

Babel configuration:

module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  "plugins": [
    ["i18next-extract", {
        "defaultNS" : "strings",
        "outputPath" : "lang/{{locale}}/{{ns}}.json",
        "discardOldKeys" : true,
      },
    ],
  ]
};

Expected behavior

Have the extraction generate the key and key_plural entries with proper default values.

{
 "TestKey": "Test",
 "TestKey_plural": "Tests"
}

What actually happens

Your environment

  • OS: MacOS 10.15.6
  • Plugin version (e.g. 0.3.0): 0.7.2
  • Node version (e.g. 12.13.0): 14.7.0

aaronfg avatar Aug 05 '20 18:08 aaronfg

I've also struggled with handling extraction with pluralization. You could use i18next-intervalplural-postprocessor then you would write something like this

t('TestKey_interval', { count: count, defaultValue: '(1){test};(2-inf)}{tests};' })

that way you could extract the pluralization, But I don't know if that's the best way

hazem3500 avatar Aug 16 '20 09:08 hazem3500

Interesting.

I have not seen that syntax with the semicolons inside the default value string to separate the defaults.

I'll take a look at the postprocessor and see how that works.

thanks for this!

aaronfg avatar Aug 17 '20 17:08 aaronfg

You can also consider using ICU format You can write the plural like this

<Plural
  i18nKey="TestKey"
  count={count}
  one="test"
  other="tests"
/>

hazem3500 avatar Aug 17 '20 19:08 hazem3500

This would be very useful. Any chances for making it work?

kamil7x avatar Sep 06 '22 13:09 kamil7x

Is this issue actually related to discardOldKeys in any way, as the title suggests? It may be, but I do not understand how.

Also, I'm not sure which default value you would expect to be used. I feel like having a comment hint for that purpose would be slightly "too much" and using the singular default value as default value for plurals doesn't seem correct either (because it will be considered as translated when it should be reworked). Especially with intervalplural-preprocessor, I'm not sure how all this should work together.

I'm under the impression that this is rather an issue for the translation tool: it should display singular and plurals "together", so that they can be translated in a batch. But I definitely don't have a strong opinion.

gilbsgilbs avatar Sep 06 '22 15:09 gilbsgilbs

@gilbsgilbs i18next allows to pass multiple default values, eg

function totalItems(count: number) {
  return t('total_count', {
    count,
    defaultValue_one: 'Total {{count}} item',
    defaultValue_other: 'Total {{count}} items',
  });
}

and then:

console.log(totalItems(0));     // Total 0 items
console.log(totalItems(1));     // Total 1 item
console.log(totalItems(4));     // Total 4 items
console.log(totalItems(127));   // Total 127 items

Same for other suffixes used in different languages like _few and _many

kamil7x avatar Sep 07 '22 06:09 kamil7x

I didn't know that. This is a nice feature request. I'll happily accept PRs for it.

gilbsgilbs avatar Sep 07 '22 07:09 gilbsgilbs

bump..

felicoz avatar Mar 12 '23 12:03 felicoz