Skip to content

langs/i18n: Revise the plural implementation#8456

Merged
bep merged 1 commit into
gohugoio:masterfrom
bep:fix/i18n-count
Apr 23, 2021
Merged

langs/i18n: Revise the plural implementation#8456
bep merged 1 commit into
gohugoio:masterfrom
bep:fix/i18n-count

Conversation

@bep

@bep bep commented Apr 22, 2021

Copy link
Copy Markdown
Member

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

@bep bep requested review from jmooring and removed request for jmooring April 22, 2021 09:07
@bep bep force-pushed the fix/i18n-count branch from 262e367 to 4f7db2b Compare April 22, 2021 09:23
@bep bep requested a review from jmooring April 22, 2021 09:23
@bep bep force-pushed the fix/i18n-count branch from 4f7db2b to 9c66b4d Compare April 22, 2021 09:24
@bep

bep commented Apr 22, 2021

Copy link
Copy Markdown
Member Author

@jmooring I would appreciate if you could have a look at this. Esp. look at the test cases in TestGetPluralCount to see if they make any sense. Seems that the v1 to v2 upgrade was filled with hassles, but I think this should at least improve the situation.

@bep bep force-pushed the fix/i18n-count branch 2 times, most recently from 83beb65 to 082b1ad Compare April 22, 2021 09:33
@bep

bep commented Apr 22, 2021

Copy link
Copy Markdown
Member Author

OK, I have an idea of how to make this even better. Will be back in a flash.

@bep bep marked this pull request as draft April 22, 2021 09:44
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 bep force-pushed the fix/i18n-count branch from 082b1ad to 6027c73 Compare April 22, 2021 09:52
@bep

bep commented Apr 22, 2021

Copy link
Copy Markdown
Member Author

OK, this should be ready to go.

@bep bep marked this pull request as ready for review April 22, 2021 09:53
@jmooring

jmooring commented Apr 22, 2021

Copy link
Copy Markdown
Member

A single integer argument is used as plural count

That's not going to provide the expected result with, for example, the Polish language. According to the CLDR plural rules for Polish, 100 is part of the many category, while 100.0 is part the of the other category. In another example, the plural lookup will also fail in languages such as English, Polish, and Norwegian with 1.5.

I have not finished testing yet, but wanted to provide this early feedback. I'm sorry, this stuff is messy.

@jmooring

jmooring commented Apr 23, 2021

Copy link
Copy Markdown
Member

I think that allowing both of these constructs will lead to problems.

i18n/en.toml

[cat]
one = "{{ .Count }} cat"
other = "{{ .Count }} cats"

[dog]
one = "{{ . }} dog"
other = "{{ . }} dogs" 

I will have to remember to call {{ T "cat" (dict "Count" 2) }} when translating cat, and {{ T "dog" 2 }} when translating dog. I think it would easier if we could map the single value in my dog example to {{ .Count }} in the TOML file:

[cat]
one = "{{ .Count }} cat"
other = "{{ .Count }} cats"

[dog]
one = "{{ .Count }} dog"
other = "{{ .Count }} dogs" 

And let me call it either way:

{{ T "cat" (dict "Count" 2) }}
{{ T "dog" 2 }}
@bep

bep commented Apr 23, 2021

Copy link
Copy Markdown
Member Author

I think that allowing both of these constructs will lead to problems.

The "support both" is just to avoid breaking old templates, and what you suggest isn't technically feasible (or, not without spending a stupid amount of time on it; remember: you can pass any object as context into the translation func).

My thought about this going forward is that:

  • You should be able to look at the i18n template and see what it needs, no ".Count" magic
  • The plural count is determined by either the single integer (or string, float) argument or if it's a composite, the .Count field method.

I'll merge this. It's certainly an improvement.

@bep bep merged commit 537c905 into gohugoio:master Apr 23, 2021
@github-actions

Copy link
Copy Markdown

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Apr 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

2 participants