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

Add lost pluralizationRules option to documentation #921

Merged
merged 1 commit into from
Jun 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion decls/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ declare type IntlAvailability = {
};

declare type PluralizationRules = {
[lang: string]: (choice: number, choicesLength: number) => number,
[lang: string]: GetChoiceIndex,
}

declare interface I18n {
Expand Down
38 changes: 36 additions & 2 deletions vuepress/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Component based localization option.

Localize the locale message of `key`. Localize in preferentially component locale messages than global locale messages. If not specified component locale messages, localize with global locale messages. If you specified `locale`, localize the locale messages of `locale`. If you specified `key` of list / named formatting local messages, you must specify `values` too. For `values` more details see [Formatting](../guide/formatting.md).

If default pluralization does not suit your needs, see [pluralization rules in constructor options](#pluralizationrules) and [custom pluralization](../guide/pluralization.md).

:::danger Tip
Note that you need to guarantee this context equal to component instance in lifecycle methods (e.g. in `data` options, `const $t = this.$t.bind(this)`).
:::
Expand Down Expand Up @@ -233,7 +235,7 @@ The formatter that implemented with `Formatter` interface.

> :new: 8.15.0+
* **Type:** `Modifier`
* **Type:** `Modifiers`

* **Default:** `lower` and `upper` modifiers

Expand Down Expand Up @@ -294,6 +296,25 @@ Whether suppress warnings when falling back to either `fallbackLocale` or `root`
If `true`, warnings will be generated only when no translation is available at all, and not for fallbacks.
If you use regular expression, you can suppress the fallback warnings that it match `key` (e.g. `$t`).

#### pluralizationRules

> 8.5+
* **Type:** `PluralizationRules`

* **Default:** `{}`

A set of rules for word pluralization in a following format:
```js
{
// Key - locale for the rule to be applied to.
// Value - mapping function that maps a choice index from `$tc` to the actual choice of the plural word. (See getChoiceIndex for details)
'ru': function(choice, choiceIndex) => Number/* index of the plural word */;
'en': function(choice, choiceIndex) => Number/* index of the plural word */;
'jp': function(choice, choiceIndex) => Number/* index of the plural word */;
}
```
#### preserveDirectiveContent
> 8.7+
Expand Down Expand Up @@ -434,6 +455,16 @@ Whether suppress warnings outputted when localization fails.
Whether suppress fallback warnings when localization fails.
#### pluralizationRules
> 8.5+
* **Type:** `PluralizationRules`
* **Read/Write**
A set of locale-dependent rules for word pluralization.
#### preserveDirectiveContent
> 8.7+
Expand Down Expand Up @@ -481,12 +512,15 @@ A handler for post processing of translation.
* **Return:** `finalChoice {number}`
Get pluralization index for current pluralizing number and a given amount of choices. Can be overridden through prototype mutation:
Get pluralization index for current pluralizing number and a given amount of choices.
Can be overridden through prototype mutation:
```js
VueI18n.prototype.getChoiceIndex = /* custom implementation */
```
However, for most usages [pluralizationRules constructor option](#pluralizationrules) should be enough.
#### getLocaleMessage( locale )
* **Arguments:**
Expand Down
73 changes: 39 additions & 34 deletions vuepress/guide/pluralization.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,47 +81,47 @@ Output below:

Such pluralization, however, does not apply to all languages (Slavic languages, for example, have different pluralization rules).

In order to implement these rules you can override the `VueI18n.prototype.getChoiceIndex` function.
In order to implement these rules you can pass an optional `pluralizationRules` object into `VueI18n` constructor options.

Very simplified example using rules for Slavic languages (Russian, Ukrainian, etc.):
```js

const defaultImpl = VueI18n.prototype.getChoiceIndex

/**
* @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} an overall amount of available choices
* @returns a final choice index to select plural word by
**/
VueI18n.prototype.getChoiceIndex = function (choice, choicesLength) {
// this === VueI18n instance, so the locale property also exists here
if (this.locale !== 'ru') {
// proceed to the default implementation
return defaultImpl.apply(this, arguments)
}

if (choice === 0) {
return 0;
new VueI18n({
// Key - language to use the rule for, `'ru'`, in this case
// Value - function to choose right plural form
pluralizationRules: {
/**
* @param choice {number} a choice index given by the input to $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} an overall amount of available choices
* @returns a final choice index to select plural word by
*/
'ru': function(choice, choicesLength) {
// this === VueI18n instance, so the locale property also exists here

if (choice === 0) {
return 0;
}

const teen = choice > 10 && choice < 20;
const endsWithOne = choice % 10 === 1;

if (choicesLength < 4) {
return (!teen && endsWithOne) ? 1 : 2;
}
if (!teen && endsWithOne) {
return 1;
}
if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2;
}

return (choicesLength < 4) ? 2 : 3;
}
}

const teen = choice > 10 && choice < 20;
const endsWithOne = choice % 10 === 1;

if (!teen && endsWithOne) {
return 1;
}

if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2;
}

return (choicesLength < 4) ? 2 : 3;
}
})
```

This would effectively give this:


```javascript
const messages = {
ru: {
Expand All @@ -130,7 +130,8 @@ const messages = {
}
}
```
Where the format is `0 things | 1 thing | few things | multiple things`.
Where the format is `0 things | things count ends with 1 | things count ends with 2-4 | things count ends with 5-9, 0 and teens (10-19)`.
P.S. Slavic pluralization is a pain, you can read more about it [here](http://www.russianlessons.net/lessons/lesson11_main.php).

Your template still needs to use `$tc()`, not `$t()`:

Expand Down Expand Up @@ -161,3 +162,7 @@ Which results in:
<p>11 бананов</p>
<p>31 банан</p>
```

### Default pluralization

If your current locale is not found in a pluralization map, the [default](#pluralization) rule of the english language will be used.
39 changes: 36 additions & 3 deletions vuepress/ru/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ sidebar: auto

Получение переведённого сообщения по ключу `key` с использованием плюрализации. Сообщения локализации компонента имеют приоритет над глобальными сообщениями. Если сообщений локализации в компоненте нет, то локализация осуществляется с помощью глобальных сообщений локализации. Если указана `locale`, то используются сообщения локализации из `locale`. Если указано строковое значение для `values`, то локализация выполняется для этого значения. Если указано значение Array или Object в `values`, то необходимо указывать с `values` из \$t.

Если вам не подходит реализация плюрализации по умолчанию, смотрите [pluralization rules в опциях конструктора](#pluralizationrules) и [пользовательскую плюрализацию](../guide/pluralization.md).

:::danger Совет
Обратите внимание, что в хуках жизненного цикла контекст должен быть экземпляром компонента (например в опции `data`, `const $tc = this.$tc.bind(this)`).
:::
Expand Down Expand Up @@ -238,7 +240,7 @@ sidebar: auto

> :new: Добавлено в версии 8.15.0+
- **Тип:** `Modifier`
- **Тип:** `Modifiers`

- **По умолчанию:** модификаторы `lower` и `upper`

Expand Down Expand Up @@ -298,6 +300,25 @@ sidebar: auto

При значении `true` предупреждения будут генерироваться только если недоступна локализация вообще, а не для случаев использования запасной локали. При использовании регулярного выражения можно отключать предупреждения которые будут соответствовать `key` (например, `$t`).

#### pluralizationRules

> 8.5+
* **Тип:** `PluralizationRules`

* **По умолчанию:** `{}`

Набор правил для плюрализации в следующем формате:
```js
{
// Ключ - локаль для которой будет применяться правило.
// Value - функция для получения индекса варианта плюрализации от текущего числа и заданного количества вариантов. (См. функцию getChoiceIndex)
'ru': function(choice, choiceIndex) => Number/* index of the plural word */;
'en': function(choice, choiceIndex) => Number/* index of the plural word */;
'jp': function(choice, choiceIndex) => Number/* index of the plural word */;
}
```
#### preserveDirectiveContent
> Добавлено в версии 8.7+
Expand Down Expand Up @@ -438,6 +459,16 @@ sidebar: auto
Отключение предупреждений выводимых при ошибке использования запасной локализации.
#### pluralizationRules
> 8.5+
- **Тип:** `PluralizationRules`
- **Чтение/Запись**
Набор зависимых от локали правил плюрализации.
#### preserveDirectiveContent
> Добавлено в версии 8.7+
Expand Down Expand Up @@ -491,6 +522,8 @@ sidebar: auto
VueI18n.prototype.getChoiceIndex = /* пользовательская реализация */
```
Однако в большинстве случаев достаточно передать нужную функцию в [pluralizationRules опцию конструктора](#pluralizationrules).
#### getLocaleMessage( locale )
- **Аргументы:**
Expand Down Expand Up @@ -848,7 +881,7 @@ new Vue({
[Локализация чисел](../guide/number.md#custom-formatting)
## Специальный атрибуты
## Специальные атрибуты
### place
Expand All @@ -858,7 +891,7 @@ new Vue({
Используется при интерполяции компонента для указания индекса при форматировании списком или ключа при именованном форматировании.
Подробнее об использовании можно изучить в разделе по ссылке ниже.
Подробнее об использовании в разделе по ссылке ниже.
#### См. также:
Expand Down
75 changes: 40 additions & 35 deletions vuepress/ru/guide/pluralization.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,44 +84,45 @@ const messages = {

## Пользовательская плюрализация

Стандартная реализация плюрализации может быть не применима ко всем языкам (к примеру, в Славянских языках другие правила множественности).
Стандартная реализация плюрализации не подходит для некоторых языков (к примеру, в славянских языках другие правила множественности).

Можно указать собственную реализацию переопределив функцию `VueI18n.prototype.getChoiceIndex`.

Очень упрощённый пример правил для Славянских языков (Русский, Украинский и другие):
Можно предоставить собственную реализацию, передав `pluralizationRules` в конструктор `VueI18n`.

Упрощенный пример для славянских языков (Русский, Украинский и другие):
```js
const defaultImpl = VueI18n.prototype.getChoiceIndex

/**
* @param choice {number} индекс выбора, переданный в $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} общее количество доступных вариантов
* @returns финальный индекс для выбора соответственного варианта слова
**/
VueI18n.prototype.getChoiceIndex = function(choice, choicesLength) {
// this === экземпляр VueI18n, поэтому свойство locale также здесь существует
if (this.locale !== 'ru') {
// возвращаемся к реализации по умолчанию
return defaultImpl.apply(this, arguments)
}

if (choice === 0) {
return 0
}

const teen = choice > 10 && choice < 20
const endsWithOne = choice % 10 === 1

if (!teen && endsWithOne) {
return 1
new VueI18n({
// Ключ - язык, для которого будет применяться правило, в этом примере - `'ru'`
// Value - функция плюрализации
pluralizationRules: {
/**
* @param choice {number} индекс выбора, переданный в $tc: `$tc('path.to.rule', choiceIndex)`
* @param choicesLength {number} общее количество доступных вариантов
* @returns финальный индекс для выбора соответственного варианта слова
*/
'ru': function(choice, choicesLength) {
// this === VueI18n instance, so the locale property also exists here

if (choice === 0) {
return 0;
}

const teen = choice > 10 && choice < 20;
const endsWithOne = choice % 10 === 1;

if (choicesLength < 4) {
return (!teen && endsWithOne) ? 1 : 2;
}
if (!teen && endsWithOne) {
return 1;
}
if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2;
}

return (choicesLength < 4) ? 2 : 3;
}
}

if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2
}

return choicesLength < 4 ? 2 : 3
}
})
```

Такая реализация позволит использовать:
Expand All @@ -135,7 +136,7 @@ const messages = {
}
```

Для такого формата вариантов `0 вещей | 1 вещь | несколько вещей | множество вещей`.
Для такого формата вариантов `0 вещей | количество вещей заканчивается на 1 | количество вещей заканчивается на 2-4 | количество вещей заканчивается на 5-9, 0 и числа от 11 до 19`.

В шаблоне, по-прежнему, необходимо использовать `$tc()` вместо `$t()`:

Expand Down Expand Up @@ -166,3 +167,7 @@ const messages = {
<p>11 бананов</p>
<p>31 банан</p>
```

### Плюрализация по умолчанию

Если для используемой локали не предоставить правило плюрализации, [по умолчанию](#pluralization) будет использовано правило для английского языка