Replies: 4 comments
-
@movermeyer tagging you for visibility, I came across your two issues while looking into this :) |
Beta Was this translation helpful? Give feedback.
-
Keep in mind that I'm not a FED, nor do I know much about Polaris. but I do know pluralization fairly well. Singular vs Specific plural vs Generic plural"Singular" is only an English (and a few other languages) concept. There should not be any difference in the calling code for any of these cases. You always have to pass in the count, regardless of whether the count is 1 or not. Framing the discussion around these three cases feels strange and suggests that something is wrong.
I'm not sure I understand the difference between "Specific plural" and "Generic plural". Is it just whether or not you are using the resource name as an interpolation? Interpolationi18n.translate('Polaris.IndexTable.selectAllItems', {
resourceNamePlural: pluralize(resourceNameFormatString, itemCount),
}); The entire string should be translated into the language's required plural forms rather than using an interpolation of the resource name.
|
Beta Was this translation helpful? Give feedback.
-
@lhoffbeck I agree with Michael on this one:
Interpolating This is compounded by the liberal use of articles in the English UI. That particular string has an interesting history:
The above is just to add more context to this discussion. Really happy to see someone from outside our team actually giving a dime about this problem! Much appreciated :) We're always happy to discuss i18n stuff in help-i18n-and-translation, especially if this will help us gain more traction on this issue. |
Beta Was this translation helpful? Give feedback.
-
@movermeyer / @rafal-nedzarek-loc thank you both for your replies! Sorry for the delayed response, completely missed the notification on this 😅
100% agree, in all cases the solution for interpolation is that we'd need to use a Definitely not saying
This was a bad copy-paste, updated the description for clarity. You're right, with interpolation there's still the chance that sentences are wrong.
As an ideal, totally agree. This would also help with capitalization issues, polaris sometimes assumes things should be I focused on improving the interpolation pattern because it's what's baked into polaris-react currently, and gets us to a closer (but not perfect) solution for a number of languages. It looks like any of the suggested approaches could help with Rafal's example of Depending on how it's set up, changing to an approach where the entire string is translated increases the footprint of a component's props or usage. I'm not sure what the appetite is for that within the polaris team or for consumers given how English-centric so much of Shopify is... as we continue to grow internationally the impact of not doing something like this will become greater though. Super happy to jam with either/both of you guys on this and see if we can kick this thing further down the road! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
When components require that a consumer pass a pluralized version of a string, Polaris currently restricts the consumer to a English-centric pluralization format. This isn't very inclusive and can reduce merchant trust in our UI for non-English locales.
Existing issues:
Goal
Hopefully this RFC helps build context, but I'm planning to keep this pretty surface-level for now--just wanted to get a gut check on approach and see if this is something that has legs.
So... what's the issue?
We can look at
IndexTable
as a specific example. The component expects 2resourceName
values:The consumer then provides this value when using the component:
Within
IndexTable
, these values are then used in a few contexts:(1) Singular: refers to 1 of the resource item (*note: this is buggy because not all languages have a concept of singular)
(2) Specific plural: associated with an item count (*note: this is buggy because not all languages have a single plural value)
(3) Generic plural: not associated with any item count
The Issue
(stolen from @movermeyer's great polaris-react issue #4031)
While we only handle 2 pluralization cases, the Unicode CLDR rules give us 6 different cases we'd need to account for in order to handle this correctly for all locales. This Pluralization for JavaScript article is a fantastic resource for further reading, but the relevant information for our case is:
Effectively, our copy may be completely wrong in other locales. As an example under our current implementation, in Arabic we may have:
Issue Scope
Other polaris components that may have this same issue are:
Approaches
None of these go too deep, but wanted to suggest a few alternate approaches.
Note that Approach 1 & 2 require (1) that we add a new JS package that handles CLDR logic, and (2) that the user add the current locale to the Polaris scope, probably via
<AppProvider>
(my understanding is that we don't currently keep this state in polaris anywhere). However, I think this might be okay for a few reasons:en.json
,de.json
, etc. Web issues #24886 and #24887 are examples of how our currently local-less state are hurting us. As we continue to add additional languages and locales, this issue will only become more pronounced. In order to fix this we will need to add some CLDR tooling.Approach 3 is slightly more painful for consumers to implement, but doesn't require us to make any major changes in the current behavior of Polaris.
Approach 1: MessageFormat + client passes a single format string
This approach uses the
MessageFormat
utility from the OpenJS Foundation to parse a formatstring based on locale and a provided count. Message format uses the ICU message format standard to provide pluralization rules in a single format string.Prerequisites
@messageformat/core
package<IndexProvider>
could be a good solution)This is how this could work in our IndexTable example:
The consumer provides this value when using the component:
Usage then looks like:
(1) Singular: refers to 1 of the resource item
(2) Specific plural: associated with an item count THIS IS POTENTIALLY WRONG FOR NON-ENGLISH LOCALES
(3) Generic plural: not associated with any item count
Pros:
Cons:
Approach 2: Use Globalize to determine correct plural format
This approach uses the
pluralGenerator
utility from the GlobalizeJS package to programmatically determine which plural form (zero
,one
,two
,few
,many
, orother
) should be used based on a count and the current locale.Prerequisites
globalize
andglobalize/plural
packagesone
,two
, ...)<IndexProvider>
could be a good solution)This is how this could work in our IndexTable example:
The consumer provides this value when using the component:
Usage then looks like:
(1) Singular: refers to 1 of the resource item
(2) Specific plural: associated with an item count
(3) Generic plural: not associated with any item count
Pros:
Cons:
Approach 3: Pluralize via injected callback
In this approach, the client passes a callback function that accepts a count variable and returns the correct translation.
Prerequisites (none)
This is how this could work in our IndexTable example:
The consumer provides this value when using the component:
Usage then looks like:
(1) Singular: refers to 1 of the resource item
(2) Specific plural: associated with an item count
(3) Generic plural: not associated with any item count
Pros:
Cons:
Conclusion
My hope is that these findings take work off someone else's plate :) My personal feeling is that to fix current issues and as we support more locales/languages and as Polaris grows, we're going to need to make the system locale-aware. Given that, of the 3 approaches, option 1 or 2 may be a better long-term fit.
Beta Was this translation helpful? Give feedback.
All reactions