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

Fix singular/plural translation section #1410

Closed
jmooring opened this issue Apr 8, 2021 · 4 comments
Closed

Fix singular/plural translation section #1410

jmooring opened this issue Apr 8, 2021 · 4 comments

Comments

@jmooring
Copy link
Member

jmooring commented Apr 8, 2021

https://gohugo.io/content-management/multilingual/#query-a-singularplural-translation

In order to meet singular/plural requirement, you must pass a dictionary (map) with a numeric .Count property to the i18n function.

No.

The function will read .Count from .ReadingTime

No.

In case you need to pass custom data: ((dict "Count" 25) is minimum requirement)

No.

Maybe some of this was true in an earlier version, but none of it is true now.

  1. .ReadingTime is just an int. It doesn't have a "built-in Count" property.

  2. The only way to get T/i18n to return the singular value from the translation table is to pass the integer value 1.

    {{ T "kitten" 1 }}
    
  3. If you pass a float it complains.

    {{ T "kitten" 1.5 }}
    

    invalid plural count 1.5 for message id "kitten": floats should be formatted into a string

  4. T/i18n always returns the plural value from the translation table when you pass a string, slice, or dict. All of these return the plural value:

    {{ T "kitten" (dict "Count" 1 "foo" "bar") }}
    {{ T "kitten" (dict "count" 1 "foo" "bar") }}
    {{ T "kitten" (dict "Count" "1" "foo" "bar") }}
    {{ T "kitten" (dict "count" "1" "foo" "bar") }}
    

[hugo v0.83.0-DEV+extended linux/amd64 BuildDate=unknown]

@jmooring
Copy link
Member Author

jmooring commented Apr 8, 2021

So I think this page currently describes how go-i18n V1 behaved. We are now using go-i18n V2.

bep added a commit to bep/hugo that referenced this issue Apr 22, 2021
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as `.Count`. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

Fixes gohugoio#8454
Closes gohugoio#7822
See gohugoio/hugoDocs#1410
bep added a commit to bep/hugo that referenced this issue Apr 22, 2021
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as `.Count`. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

Fixes gohugoio#8454
Closes gohugoio#7822
See gohugoio/hugoDocs#1410
bep added a commit to bep/hugo that referenced this issue Apr 22, 2021
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as `.Count`. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

Fixes gohugoio#8454
Closes gohugoio#7822
See gohugoio/hugoDocs#1410
@jmooring
Copy link
Member Author

jmooring commented Apr 22, 2021

The i18n files allow for more than just singular (one) and plural (other) categories, but it depends on the language.

The Unicode Common Locale Data Repository (CLDR) defines plural rules for each language. Take a look at the "cardinal" categories in this table. Examples:

Language Code Cardinal Categories
English en one, other
German de one, other
Irish ga one, two, few, many, other
Italian it one, other
Latvian lv zero, one, other
Norwegian Bokmål nb one, other
Norwegian Nynorsk nn one, other
Polish pl one, few, many, other
Russian ru one, few, many, other
Spanish es one, other
Welsh cy zero, one, two, few, many, other

The https://github.com/nicksnyder/go-i18n package handles the plural rules for Hugo, but there are few important things to remember.

1) Cardinal categories defined in the i18n file that are not defined in the CLDR plural rules will be ignored. In the example below, all but one and other will be ignored because the CLDR plural rules for English exclude the other cardinal categories.

i18n/en.toml

[cat]
zero = "kittens"      # ignored
one = "cat"
two = "kitties"       # ignored
few = "fur balls"   # ignored
many = "beasts"       # ignored
other = "cats"

2) When a cardinal category is defined in the CLDR plural rules but is missing from the i18n file, then (a) the value from the other category (if defined) will be substituted, and (b) a warning will be generated. For example, consider this Polish translation:

i18n/pl.toml

[cat]
one = "kot"
other = "koty"

The CLDR plural rules specify two additional cardinal categories for the Polish language: few and many.

Statement Result Warning
{{ i18n "cat" 0 }} koty WARN ... "cat" has no plural form "many"
{{ i18n "cat" 1 }} kot N/A
{{ i18n "cat" 2 }} koty WARN ... "cat" has no plural form "few"
{{ i18n "cat" 3 }} koty WARN ... "cat" has no plural form "few"
{{ i18n "cat" 4 }} koty WARN ... "cat" has no plural form "few"
{{ i18n "cat" 5 }} koty WARN ... "cat" has no plural form "many"

3) Although the current implementation of https://github.com/nicksnyder/go-i18n uses other as a fallback category when the correct category is not defined, it was never intended to be used that way. The other category is explicitly defined by the CLDR plural rules, and is an implicit fallback only when all other categories for a given language are defined.

bep added a commit to bep/hugo that referenced this issue Apr 22, 2021
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as `.Count`. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

Fixes gohugoio#8454
Closes gohugoio#7822
See gohugoio/hugoDocs#1410
bep added a commit to bep/hugo that referenced this issue Apr 22, 2021
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as `.Count`. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

Fixes gohugoio#8454
Closes gohugoio#7822
See gohugoio/hugoDocs#1410
bep added a commit to bep/hugo that referenced this issue Apr 22, 2021
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as a int type with a `.Count` method. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

The above means that you can now do pass a single integer and both of the below will work:

```
{{ . }} minutes to read
{{ .Count }} minutes to read
```

Fixes gohugoio#8454
Closes gohugoio#7822
See gohugoio/hugoDocs#1410
bep added a commit to gohugoio/hugo that referenced this issue Apr 23, 2021
There were some issues introduced with the plural counting when we upgraded from v1 to v2 of go-i18n.

This commit improves that situation given the following rules:

* A single integer argument is used as plural count and passed to the i18n template as a int type with a `.Count` method. The latter is to preserve compability with v1.
* Else the plural count is either fetched from the `Count`/`count` field/method/map or from the value itself.
* Any data type is accepted, if it can be converted to an integer, that value is used.

The above means that you can now do pass a single integer and both of the below will work:

```
{{ . }} minutes to read
{{ .Count }} minutes to read
```

Fixes #8454
Closes #7822
See gohugoio/hugoDocs#1410
@jmooring
Copy link
Member Author

jmooring commented May 1, 2021

Additional info for when we (I) get around to updating this page. This comes into play when i18n is called without a quantity:

{{ i18n "cat" }}

This produces the same results as

{{ i18n "cat" 0 }} 

The Unicode Common Locale Data Repository (CLDR) defines plural rules for 208 languages.

For 165 of those languages, the cardinal category other is used when the quantity specified for the translation is zero.

The other 43 languages use a variety of cardinal categories when the quantity specified for the translation is zero, including zero, one, few, and many.

Language Code Cardinal Category
Akan ak one
Amharic am one
Arabic ar zero
Armenian hy one
Assamese as one
Bangla bn one
Belarusian be many
Bhojpuri bho one
Cebuano ceb one
Central Atlas Tamazight tzm one
Colognian ksh zero
Cornish kw zero
Filipino fil one
French fr one
Fulah ff one
Gujarati gu one
Gun guw one
Hindi hi one
Kabyle kab one
Kannada kn one
Langi lag zero
Latvian lv zero
Lingala ln one
Malagasy mg one
Maltese mt few
Manx gv few
Najdi Arabic ars zero
Nigerian Pidgin pcm one
Northern Sotho nso one
Persian fa one
Polish pl many
Portuguese pt one
Prussian prg zero
Punjabi pa one
Romanian ro few
Russian ru many
Sinhala si one
Tachelhit shi one
Tigrinya ti one
Ukranian uk many
Walloon wa one
Welsh cy zero
Zulu zu one

@jmooring
Copy link
Member Author

jmooring commented Jun 1, 2023

Closing in favor of #2099.

@jmooring jmooring closed this as completed Jun 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant