Skip to content

Commit

Permalink
Add lost pluralizationRules option to documentation (#921)
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandrSl committed Jun 12, 2020
1 parent 31573e1 commit 4c3ea38
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 114 deletions.
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) будет использовано правило для английского языка

0 comments on commit 4c3ea38

Please sign in to comment.