|
|
|
@ -5,44 +5,215 @@ Internationalization (I18N) refers to the process of designing a software applic
|
|
|
|
|
various languages and regions without engineering changes. For Web applications, this is of particular importance |
|
|
|
|
because the potential users may be worldwide. |
|
|
|
|
|
|
|
|
|
When developing an application it's assumed that we're relying on |
|
|
|
|
[PHP internationalization extension](http://www.php.net/manual/en/intro.intl.php). While extension covers a lot of aspects |
|
|
|
|
Yii adds a bit more: |
|
|
|
|
Locale and Language |
|
|
|
|
------------------- |
|
|
|
|
|
|
|
|
|
- It handles message translation. |
|
|
|
|
There are two languages defined in Yii application: [[\yii\base\Application::$sourceLanguage|source language]] and |
|
|
|
|
[[\yii\base\Application::$language|target language]]. |
|
|
|
|
|
|
|
|
|
Source language is the language original application messages are written in such as: |
|
|
|
|
|
|
|
|
|
Locale and Language |
|
|
|
|
------------------- |
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'I am a message!'); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
> **Tip**: Default is English and it's not recommended to change it. The reason is that it's easier to find people translating from |
|
|
|
|
> English to any language than from non-English to non-English. |
|
|
|
|
|
|
|
|
|
Target language is what's currently used. It's defined in application configuration like the following: |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
// ... |
|
|
|
|
return array( |
|
|
|
|
'id' => 'applicationID', |
|
|
|
|
'basePath' => dirname(__DIR__), |
|
|
|
|
'language' => 'ru_RU' // ← here! |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Later you can easily change it in runtime: |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
\Yii::$app->language = 'zh_CN'; |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Basic message translation |
|
|
|
|
------------------------- |
|
|
|
|
|
|
|
|
|
### Strings translation |
|
|
|
|
|
|
|
|
|
Yii basic message translation that works without additional PHP extension and |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Named placeholders |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
$username = 'Alexander'; |
|
|
|
|
echo \Yii::t('app', 'Hello, {username}!', array( |
|
|
|
|
'username' => $username, |
|
|
|
|
)); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
### Positional placeholders |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
$sum = 42; |
|
|
|
|
echo \Yii::t('app', 'Balance: {0}', $sum); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
> **Tip**: When messages are extracted and passed to translator, he sees strings only. For the code above extracted message will be |
|
|
|
|
> "Balance: {0}". It's not recommended to use positional placeholders except when there's only one and message context is |
|
|
|
|
> clear as above. |
|
|
|
|
|
|
|
|
|
Advanced placeholder formatting |
|
|
|
|
------------------------------- |
|
|
|
|
|
|
|
|
|
In order to use advanced features you need to install and enable [intl](http://www.php.net/manual/en/intro.intl.php) PHP |
|
|
|
|
extension. After installing and enabling it you will be able to use extended syntax for placeholders. Either short form |
|
|
|
|
`{placeholderName, argumentType}` that means default setting or full form `{placeholderName, argumentType, argumentStyle}` |
|
|
|
|
that allows you to specify formatting style. |
|
|
|
|
|
|
|
|
|
Full reference is [available at ICU website](http://icu-project.org/apiref/icu4c/classMessageFormat.html) but since it's |
|
|
|
|
a bit crypric we have our own reference below. |
|
|
|
|
|
|
|
|
|
### Numbers |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
$sum = 42; |
|
|
|
|
echo \Yii::t('app', 'Balance: {0, number}', $sum); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
You can specify one of the built-in styles (`integer`, `currency`, `percent`): |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
$sum = 42; |
|
|
|
|
echo \Yii::t('app', 'Balance: {0, number, currency}', $sum); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Or specify custom pattern: |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
$sum = 42; |
|
|
|
|
echo \Yii::t('app', 'Balance: {0, number, ,000,000000}', $sum); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
[Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1DecimalFormat.html). |
|
|
|
|
|
|
|
|
|
### Dates |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'Today is {0, date}', time()); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Built in formats (`short`, `medium`, `long`, `full`): |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'Today is {0, date, short}', time()); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Custom pattern: |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'Today is {0, date, YYYY-MM-dd}', time()); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
[Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html). |
|
|
|
|
|
|
|
|
|
### Time |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'It is {0, time}', time()); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Built in formats (`short`, `medium`, `long`, `full`): |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'It is {0, time, short}', time()); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Custom pattern: |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'It is {0, date, HH:mm}', time()); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
[Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Spellout |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', '{n,number} is spelled as {n, spellout}', array( |
|
|
|
|
'n' => 42, |
|
|
|
|
)); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
### Ordinal |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'You are {n, ordinal} visitor here!', array( |
|
|
|
|
'n' => 42, |
|
|
|
|
)); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Will produce "You are 42nd visitor here!". |
|
|
|
|
|
|
|
|
|
### Duration |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'You are here for {n, duration} already!', array( |
|
|
|
|
'n' => 42, |
|
|
|
|
)); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Will produce "You are here for 47 sec. already!". |
|
|
|
|
|
|
|
|
|
### Plurals |
|
|
|
|
|
|
|
|
|
Different languages have different ways to inflect plurals. Some rules are very complex so it's very handy that this |
|
|
|
|
functionality is provided without the need to specify inflection rule. Instead it only requires your input of inflected |
|
|
|
|
word in certain situations. |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', 'There {n, plural, =0{are no cats} =1{is one cat} other{are # cats}}!', array( |
|
|
|
|
'n' => 0, |
|
|
|
|
)); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Will give us "There are no cats!". |
|
|
|
|
|
|
|
|
|
In the plural rule arguments above `=0` means exactly zero, `=1` stands for exactly one `other` is for any other number. |
|
|
|
|
`#` is replaced with the `n` argument value. It's not that simple for languages other than English. Here's an example |
|
|
|
|
for Russian: |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
Здесь {n, plural, =0{котов нет} =1{есть один кот} one{# кот} few{# кота} many{# котов} other{# кота}}! |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
In the above it worth mentioning that `=1` matches exactly `n = 1` while `one` matches `21` or `101`. |
|
|
|
|
|
|
|
|
|
To learn which inflection forms you should specify for your language you can referer to |
|
|
|
|
[rules reference at unicode.org](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html). |
|
|
|
|
|
|
|
|
|
### Selections |
|
|
|
|
|
|
|
|
|
You can select phrases based on keywords. The pattern in this case specifies how to map keywords to phrases and |
|
|
|
|
provides a default phrase. |
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
echo \Yii::t('app', '{name} is {gender} and {gender, select, female{she} male{he} other{it}} loves Yii!', array( |
|
|
|
|
'name' => 'Snoopy', |
|
|
|
|
'gender' => 'dog', |
|
|
|
|
)); |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
Will produce "Snoopy is dog and it loves Yii!". |
|
|
|
|
|
|
|
|
|
In the expression `female` and `male` are possible values. `other` handler values that do not match. Strings inside |
|
|
|
|
brackets are sub-expressions so could be just a string or a string with more placeholders. |
|
|
|
|
|
|
|
|
|
Formatters |
|
|
|
|
---------- |
|
|
|
|
|
|
|
|
|
Translation |
|
|
|
|
----------- |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
|
|
numeric arg \{\s*\d+\s*\} |
|
|
|
|
named arg \{\s*(\w|(\w|\d){2,})\s*\} |
|
|
|
|
|
|
|
|
|
named placeholder can be unicode!!! |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
argName [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+ |
|
|
|
|
|
|
|
|
|
message = messageText (argument messageText)* |
|
|
|
|
argument = noneArg | simpleArg | complexArg |
|
|
|
|
complexArg = choiceArg | pluralArg | selectArg | selectordinalArg |
|
|
|
|
noneArg = '{' argNameOrNumber '}' |
|
|
|
|
simpleArg = '{' argNameOrNumber ',' argType [',' argStyle] '}' |
|
|
|
|
choiceArg = '{' argNameOrNumber ',' "choice" ',' choiceStyle '}' |
|
|
|
|
pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}' |
|
|
|
|
selectArg = '{' argNameOrNumber ',' "select" ',' selectStyle '}' |
|
|
|
|
selectordinalArg = '{' argNameOrNumber ',' "selectordinal" ',' pluralStyle '}' |
|
|
|
|
choiceStyle: see ChoiceFormat |
|
|
|
|
pluralStyle: see PluralFormat |
|
|
|
|
selectStyle: see SelectFormat |
|
|
|
|
argNameOrNumber = argName | argNumber |
|
|
|
|
argName = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+ |
|
|
|
|
argNumber = '0' | ('1'..'9' ('0'..'9')*) |
|
|
|
|
argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration" |
|
|
|
|
argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText |
|
|
|
|
*/ |
|
|
|
|
In order to use formatters you need to install and enable [intl](http://www.php.net/manual/en/intro.intl.php) PHP |
|
|
|
|
extension. |
|
|
|
|