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

docs: add documentation about pluralization #7236

Merged
merged 1 commit into from
Apr 24, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions website/docs/i18n/i18n-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,11 @@ The `docusaurus write-translations` command will statically analyze all React co

The `docusaurus write-translations` command only does **static analysis** of your code. It doesn't actually run your site. Therefore, dynamic messages can't be extracted, as the message is an _expression_, not a _string_:

```tsx
```jsx
const items = [
{id: 1, title: 'Hello'},
{id: 2, title: 'World'},
]
];

function ItemsList() {
return (
Expand All @@ -236,11 +236,11 @@ function ItemsList() {

This still behaves correctly at runtime. However, in the future, we may provide a "no-runtime" mechanism, allowing the translations to be directly inlined in the React code through Babel transformations, instead of calling the APIs at runtime. Therefore, to be future-proof, you should always prefer statically analyzable messages. For example, we can refactor the code above to:

```tsx
```jsx
const items = [
{id: 1, title: <Translate>Hello</Translate>},
{id: 2, title: <Translate>World</Translate>},
]
];

function ItemsList() {
return (
Expand All @@ -258,6 +258,52 @@ You can see the calls to the translation APIs as purely _markers_ that tell Docu

:::

#### Pluralization {#pluralization}

When you run `write-translations`, you will notice that some labels are pluralized:

```json title="i18n/en/code.json"
{
// ...
"theme.blog.post.plurals": "One post|{count} posts"
// ...
}
```

Every language will have a list of [possible plural categories](https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html). Docusaurus will arrange them in the order of `["zero", "one", "two", "few", "many", "other"]`. For example, because English (`en`) has two plural forms ("one" and "other"), the translation message has two labels separated by a pipe (`|`). For Polish (`pl`) which has three plural forms ("one", "few", and "many"), you would provide three labels in that order, joined by pipes.

You can pluralize your own code's messages as well:

```jsx
import {translate} from '@docusaurus/Translate';
import {usePluralForm} from '@docusaurus/theme-common';

function ItemsList({items}) {
// `usePluralForm` will provide the plural selector for the current locale
const {selectMessage} = usePluralForm();
// Select the appropriate pluralized label based on `items.length`
const message = selectMessage(
items.length,
translate(
{message: 'One item|{count} items'},
{count: items.length},
),
);
Comment on lines +285 to +291
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm, this is what we have in our code but that looks a bit weird to me, as we translate everything and only then select

At the same time we have to pass a static message config to translate() otherwise it wouldn't be extracted

Maybe we'd need like react-intl a new method like defineMessage() that permits static extraction but without directly translating 🤷‍♂️

Not a big deal, we can keep it this way for now

return (
<>
<h2>{message}</h2>
<ul>{items.map((item) => <li key={item.id}>{item.title}</li>)}<ul>
</>
);
}
```

:::note

Docusaurus uses [`Intl.PluralRules`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules) to resolve and select plural forms. It is important to provide the right number of plural forms in the right order for `selectMessage` to work.

:::

### Translate plugin data {#translate-plugin-data}

JSON translation files are used for everything that is interspersed in your code:
Expand Down