WeblateOrg / weblate

Web based localization tool with tight version control integration.
https://weblate.org/
GNU General Public License v3.0
4.52k stars 998 forks source link

Introduce plurality handling based on angular and ngx-translate file format and schema #2855

Closed rhofer closed 5 years ago

rhofer commented 5 years ago

Situation

In web development angular together with ngx-translate is one of the most commonly used combination to handle texts and translations. Weblate supports this in its basic functionality by allowing import as JSON / JSON nested file structure.

As stated in weblate documentation, this file format doesn't allow for plurality

Request

Introduce another JSON based file format and according treatment in weblate to cover standard behavior of angular's plurality handling. Format might be called JSON angular i18nPlural.

Example

Given a simple example of a kind of a count-down with years, months and days, the basic HTML structure may looks as following:

<divclass="remaining"*ngIf="remainingTime">
    {{ roundedRemTime.years | i18nPlural: ('DATE_DIFF_MAP' | translate) ['YEAR'] }}
    {{ roundedRemTime.months | i18nPlural: ('DATE_DIFF_MAP' | translate) ['MONTH'] }}
    {{ roundedRemTime.days | i18nPlural: ('DATE_DIFF_MAP' | translate) ['DAY'] }}
</div>

Therefore, an en.json exists, which provides the following key-value structure:

"DATE_DIFF_MAP": {
      "YEAR": {
        "=0": "",
        "=1": "# year",
        "other": "# years"
      },
      "MONTH": {
        "=0": "",
        "=1": "# month",
        "other": "# months"
      },
      "DAY": {
        "=0": "",
       "=1": "# day",
        "other": "# days"
      }
}      

According angular i18nPluralPipe the very last key element is essential to map a given value to a string in order to pluralize. Where all key elements starting with = are treated as cases with exact match and other catches everything else. Additionally, # is the placeholder to be replaced with the input value and to be rendered together with the rest of the string, e.g. resulting in 1 year, 2 years, 3 years, etc.

Based on this rule, weblate should detect a situation as given above and e.g. represent the value behind DATE_DIFF_MAP.YEAR as one context with plurality.

This would allow to properly catch-up with translating languages with more complex pluralization rules, e.g. resulting in cz.json as

"DATE_DIFF_MAP": {
      "YEAR": {
        "=0": "",
        "=1": "# rok",
        "=2": "# roky",
        "=3": "# roky",
        "=4": "# roky",
        "other": "# let"
      },
      ...
}

Expected/proposed behavior

Alternatives

rhofer commented 5 years ago

@alesrosina did I cought the situation and need correctly?

nijel commented 5 years ago

Hmm, yet another format which handles plurals wrongly ;-). Using only equals really doesn't work well for many languages, because what you actually need is at least modulo operation. It would be much better if they would stick with CLDR plural names and avoid reinventing wheel...

So maybe you should add "Pro" to all alternatives - they can correctly express plurals in all languages, for example Russian or Arabic.

rhofer commented 5 years ago

got it ;-) Let me check on this, potentially my understanding and hence my description above is wrong.

rhofer commented 5 years ago

Root cause found on my side: two technolgies are mixed, where file schema technically works but does not fulfil neither technologie's specification to cover properly e.g. plurality.

Keeping this issue open until it is clear which proper data schema to be supported and implemented.

rhofer commented 5 years ago

@nijel Meanwhile we investigated in ngx translate and saw there is a proper way to handle this with ngx messageformat (ICU). I will close this issue and properly formulate a new one.