Commit 426e6c9f by Carsten Brandt

reword/structure of the i18n and formatter guide

parent 6c0dde6f
Data Formatter
==============
For formatting of outputs Yii provides a formatter class to make date more readable for users.
[[yii\i18n\Formatter]] is a helper class that is registered as an [application component](concept-components.md) name `formatter` by default.
For formatting of outputs Yii provides a formatter class to make data more readable for users.
[[yii\i18n\Formatter]] is a helper class that is registered as an [application component](concept-components.md) named `formatter` by default.
It provides a set of methods for data formatting purpose such as date/time values, numbers and other commonly used formats in a localized way.
The formatter can be used in two different ways.
1. Using the formatting methods(all formatter methods prefixed with `as`) directly:
1. Using the formatting methods (all formatter methods prefixed with `as`) directly:
```php
echo Yii::$app->formatter->asDate('2014-01-01', 'long'); // output: January 1, 2014
......@@ -18,9 +18,9 @@ The formatter can be used in two different ways.
echo Yii::$app->formatter->asDate(null); // output: (Not set)
```
2. Using the [[yii\i18n\Formatter::format()|format()]] method using the format name.
This method is used by classes like GridView and DetailView where you can specify the data format of a column in the
widget config.
2. Using the [[yii\i18n\Formatter::format()|format()]] method and the format name.
This method is also used by widgets like [[yii\grid\GridView]] and [[yii\widgets\DetailView]] where you can specify
the data format of a column in the widget configuration.
```php
echo Yii::$app->formatter->format('2014-01-01', 'date'); // output: January 1, 2014
......@@ -32,9 +32,9 @@ The formatter can be used in two different ways.
All output of the formatter is localized when the [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed.
You can configure the [[yii\i18n\Formatter::locale|locale]] property of the formatter for this. If not configured, the
application [[yii\base\Application::language|language]] is used as the locale. See the [Section on internationaization](tutorial-i18n.md) for more details.
The Formatter will then choose the correct format for dates and number according to the locale including names of month and
The Formatter will then choose the correct format for dates and numbers according to the locale including names of month and
week days translated to the current language. Date formats are also affected by the [[yii\i18n\Formatter::timeZone|timeZone]]
which will also be taken [[yii\base\Application::timeZone|from the application]] by default.
which will also be taken [[yii\base\Application::timeZone|from the application]] if not configured explicitly.
For example the date format call will output different results for different locales:
......@@ -50,16 +50,16 @@ echo Yii::$app->formatter->asDate('2014-01-01'); // output: 1 января 2014
> Note that formatting may differ between different versions of the ICU library compiled with PHP and also based on the fact whether the
> [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed or not. So to ensure your website works with the same output
> in all environments it is recommended to install the PHP intl extension in all environments and verify that the version of the ICU library
> is the same.
> is the same. See also: [Setting up your PHP environment for internationalization](tutorial-i18n.md#setup-environment).
Configuring the format
----------------------
The default format of the Formatter class can be adjusted using the properties of the formatter class.
You can adjust these values application wide by configuring the `formatter` component in your [application config](concept-configurations.md#application-configurations)
an example configuration is shown in the following.
For more details about certain properties check out the [[yii\i18n\Formatter|API documentation of the Formatter class]].
You can adjust these values application wide by configuring the `formatter` component in your [application config](concept-configurations.md#application-configurations).
An example configuration is shown in the following.
For more details about the available properties check out the [[yii\i18n\Formatter|API documentation of the Formatter class]].
```php
'components' => [
......@@ -74,6 +74,8 @@ For more details about certain properties check out the [[yii\i18n\Formatter|API
Formatting Dates
----------------
> Note: This section is under development.
TDB
See http://site.icu-project.org/ for the format.
......@@ -89,6 +91,8 @@ See http://site.icu-project.org/ for the format.
Formatting Numbers
------------------
> Note: This section is under development.
TDB
See http://site.icu-project.org/ for the format.
......@@ -105,6 +109,8 @@ See http://site.icu-project.org/ for the format.
Other formatters
----------------
> Note: This section is under development.
TDB
......
......@@ -7,62 +7,73 @@ 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.
Yii offers several tools that help with internationalisation of a website such as [message translation][],
[number and date formatting][].
Locale and Language
-------------------
There are two languages defined in Yii application: [[yii\base\Application::$sourceLanguage|source language]] and
There are two languages defined in the 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:
Source language is the language original application messages are written in directly in the code such as:
```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:
The target language is the language that should be used to display the current page i.e. the language that original messages need
to be translated to. It is defined in the application configuration like the following:
```php
// ...
return [
'id' => 'applicationID',
'basePath' => dirname(__DIR__),
'language' => 'ru-RU' // <- here!
// ...
'language' => 'ru-RU', // <- here!
// ...
]
```
Later you can easily change it in runtime:
> **Tip**: The default value for the [[yii\base\Application::$sourceLanguage|source language]] is English and it is
> recommended to keep this value. The reason is that it's easier to find people translating from
> English to any language than from non-English to non-English.
You may set the application language at runtime to set it to a language the user has chosen.
This has to be done at a point before any output is generated so that it affects all the output correctly.
Therefor just change the application property to the desired value:
```php
\Yii::$app->language = 'zh-CN';
```
Format is `ll-CC` where `ll` is two- or three-letter lowercase code for a language according to
[ISO-639](http://www.loc.gov/standards/iso639-2/) and `CC` is country code according to
The format for the language/locale is `ll-CC` where `ll` is a two- or three-letter lowercase code for a language according to
[ISO-639](http://www.loc.gov/standards/iso639-2/) and `CC` is the country code according to
[ISO-3166](http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html).
If there's no translation for `ru-RU` Yii will try `ru` as well before failing.
> **Note**: you can further customize details specifying language
> [as documented in the ICU project](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept).
> **Note**: For more information on the concept and syntax of locales, check the
> [documentation of the ICU project](http://userguide.icu-project.org/locale#TOC-The-Locale-Concept).
Message translation
-------------------
### Basics
Message translation is used to translate messages that are ouput by an applicaiton to different languages
so that users from different countries can use the application in their native language.
Yii basic message translation in its basic variant works without additional PHP extension. What it does is finding a
translation of the message from source language into target language. Message itself is specified as the second
`\Yii::t` method parameter:
The message translation feature in Yii works simply as finding a
translation of the message from a source language into a target language.
To use the message translation feature you wrap your original message strings with a call to the [[Yii::t()]] method.
The first parameter of this method takes a category which helps to distingish the source of messages in differnet parts
of the application and the second parameter is the message itself.
```php
echo \Yii::t('app', 'This is a string to translate!');
```
Yii tries to load appropriate translation from one of the message sources defined via `i18n` component configuration:
Yii tries to load an appropriate translation according to the current [[yii\base\Application::$language|application language]]
from one of the message sources defined in the `i18n` [application component](concept-components.md).
A message source is a set of files or a database that provides translation messages.
The following configuration example defines a messages source that takes the messages from PHP files:
```php
'components' => [
......@@ -84,26 +95,24 @@ Yii tries to load appropriate translation from one of the message sources define
```
In the above `app*` is a pattern that specifies which categories are handled by the message source. In this case we're
handling everything that begins with `app`. You can also specify default translation, for more info see [this example](i18n.md#examples).
`class` defines which message source is used. The following message sources are available:
handling everything that begins with `app`. Message files are located in `@app/messages`, the `messages` directory
in your application directory. The [[yii\i18n\PhpMessageSource::fileMap|fileMap]] array
defines which file is to be used for which category.
Instead of configuring `fileMap` you can rely on convention which is to use the category name as the file name
(e.g. category `app/error` will result in the file name `app/error.php` under the [[yii\i18n\PhpMessageSource::basePath|basePath]].
- PhpMessageSource that uses PHP files.
- GettextMessageSource that uses GNU Gettext MO or PO files.
- DbMessageSource that uses database.
When translating the message for `\Yii::t('app', 'This is a string to translate!')` and an application language `ru-RU`, Yii
will first look for a file `@app/messages/ru-RU/app.php` to retrieve the list of available translations.
If there is file `ru-RU` it will try `ru` as well before failing.
`basePath` defines where to store messages for the currently used message source. In this case it's `messages` directory
in your application directory. In case of using database this option should be skipped.
Beside storing messages in PHP files (using [[yii\i18n\PhpMessageSource|PhpMessageSource]]) Yii provides two other
classes:
`sourceLanguage` defines which language is used in `\Yii::t` second argument. If not specified, application's source
language is used.
- [[yii\i18n\GettextMessageSource]] that uses GNU Gettext MO or PO files.
- [[yii\i18n\DbMessageSource]] that uses a database.
`fileMap` specifies how message categories specified in the first argument of `\Yii::t()` are mapped to files when
`PhpMessageSource` is used. In the example we're defining two categories `app` and `app/error`.
Instead of configuring `fileMap` you can rely on convention which is `BasePath/messages/LanguageID/CategoryName.php`.
#### Named placeholders
### Named placeholders
You can add parameters to a translation message that will be substituted with the corresponding value after translation.
The format for this is to use curly brackets around the parameter name as you can see in the following example:
......@@ -117,7 +126,7 @@ echo \Yii::t('app', 'Hello, {username}!', [
Note that the parameter assignment is without the brackets.
#### Positional placeholders
### Positional placeholders
```php
$sum = 42;
......@@ -129,14 +138,12 @@ echo \Yii::t('app', 'Balance: {0}', $sum);
### 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
In order to use advanced features you need to install and enable the [intl PHP extension](http://www.php.net/manual/en/intro.intl.php).
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 cryptic we have our own reference below.
A complete reference is available at the [ICU website](http://icu-project.org/apiref/icu4c/classMessageFormat.html) but we will show some examples in the following.
#### Numbers
......@@ -152,7 +159,7 @@ $sum = 42;
echo \Yii::t('app', 'Balance: {0, number, currency}', $sum);
```
Or specify custom pattern:
Or specify a custom pattern:
```php
$sum = 42;
......@@ -167,16 +174,16 @@ echo \Yii::t('app', 'Balance: {0, number, ,000,000000}', $sum);
echo \Yii::t('app', 'Today is {0, date}', time());
```
Built in formats (`short`, `medium`, `long`, `full`):
Built in formats are `short`, `medium`, `long`, and `full`:
```php
echo \Yii::t('app', 'Today is {0, date, short}', time());
```
Custom pattern:
You may also specify a custom pattern:
```php
echo \Yii::t('app', 'Today is {0, date, YYYY-MM-dd}', time());
echo \Yii::t('app', 'Today is {0, date, yyyy-MM-dd}', time());
```
[Formatting reference](http://icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html).
......@@ -187,13 +194,13 @@ echo \Yii::t('app', 'Today is {0, date, YYYY-MM-dd}', time());
echo \Yii::t('app', 'It is {0, time}', time());
```
Built in formats (`short`, `medium`, `long`, `full`):
Built in formats are `short`, `medium`, `long`, and `full`:
```php
echo \Yii::t('app', 'It is {0, time, short}', time());
```
Custom pattern:
You may also specify a custom pattern:
```php
echo \Yii::t('app', 'It is {0, date, HH:mm}', time());
......@@ -218,7 +225,6 @@ Will produce "You are 42nd visitor here!".
#### Duration
```php
echo \Yii::t('app', 'You are here for {n, duration} already!', ['n' => 47]);
```
......@@ -229,7 +235,7 @@ Will produce "You are here for 47 sec. already!".
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.
words in certain situations.
```php
echo \Yii::t('app', 'There {n, plural, =0{are no cats} =1{is one cat} other{are # cats}}!', ['n' => 0]);
......@@ -247,14 +253,14 @@ for Russian:
In the above it worth mentioning that `=1` matches exactly `n = 1` while `one` matches `21` or `101`.
Note that if you are using placeholder twice and one time it's used as plural another one should be used as number else
Note that if you are using a placeholder twice and one time it's used as `plural` another one should be used as `number` else
you'll get "Inconsistent types declared for an argument: U_ARGUMENT_TYPE_MISMATCH" error:
```
Total {count, number} {count, plural, one{item} other{items}}.
```
To learn which inflection forms you should specify for your language you can referrer to
To learn which inflection forms you should specify for your language you can referrer to the
[rules reference at unicode.org](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html).
#### Selections
......@@ -271,13 +277,13 @@ echo \Yii::t('app', '{name} is {gender} and {gender, select, female{she} male{he
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
In the expression `female` and `male` are possible values. `other` handles values that do not match. Strings inside
brackets are sub-expressions so could be just a string or a string with more placeholders.
### Specifying default translation
You can specify default translation that will be used as a fallback for categories that don't match any other translation.
This translation should be marked with `*`. In order to do it add the following to the config file (for the `yii2-basic` application it will be `web.php`):
You can specify default translations that will be used as a fallback for categories that don't match any other translation.
This translation should be marked with `*`. In order to do it add the following to the application config:
```php
//configure i18n component
......@@ -291,8 +297,8 @@ This translation should be marked with `*`. In order to do it add the following
],
```
Now you can use categories without configuring each one that is similar to Yii 1.1 behavior.
Messages for the category will be loaded from a file under default translation `basePath` that is `@app/messages`:
Now you can use categories without configuring each one, which is similar to Yii 1.1 behavior.
Messages for the category will be loaded from a file under the default translation `basePath` that is `@app/messages`:
```php
echo Yii::t('not_specified_category', 'message from unspecified category');
......@@ -302,7 +308,7 @@ Message will be loaded from `@app/messages/<LanguageCode>/not_specified_category
### Translating module messages
If you want to translate messages for a module and avoid using a single translation file for all messages, you can make it like the following:
If you want to translate messages for a module and avoid using a single translation file for all messages, you can do it like the following:
```php
<?php
......@@ -348,7 +354,7 @@ use convention of category mapping to the same named file and use `Module::t('va
### Translating widgets messages
Same rules can be applied for widgets too, for example:
The same rule as applied for Modules above can be applied for widgets too, for example:
```php
<?php
......@@ -400,34 +406,33 @@ Instead of using `fileMap` you can simply use convention of category mapping to
### Translating framework messages
Sometimes you want to correct default framework message translation for your application. In order to do so configure
`i18n` component like the following:
Yii comes with default translation messages for validation errors and some other strings. These messages are all
in the category `yii`. Sometimes you want to correct default framework message translation for your application.
In order to do so configure the `i18n` [application component](concept-components.md) like the following:
```php
'components' => [
'i18n' => [
'translations' => [
'yii' => [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en-US',
'basePath' => '/path/to/my/message/files'
],
'i18n' => [
'translations' => [
'yii' => [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en-US',
'basePath' => '@app/messages'
],
],
],
```
Now you can place your adjusted translations to `/path/to/my/message/files`.
Now you can place your adjusted translations to `@app/messages/<language>/yii.php`.
### Handling missing translations
If the translation is missing at the source, Yii displays the requested message content. Such behavior very convenient
If the translation is missing at the source, Yii displays the requested message content. Such behavior is very convenient
in case your raw message is a valid verbose text. However, sometimes it is not enough.
You may need to perform some custom processing of the situation, when requested translation is missing at the source.
This can be achieved via 'missingTranslation' event of the [[yii\i18n\MessageSource]].
This can be achieved using the [[yii\i18n\MessageSource::EVENT_MISSING_TRANSLATION|missingTranslation]]-event of [[yii\i18n\MessageSource]].
For example: lets mark all missing translations with something notable, so they can be easily found at the page.
First we need to setup event handler, this can be done via configuration:
For example to mark all missing translations with something notable, so they can be easily found at the page we
first we need to setup event handler. This can be done in the application configuration:
```php
'components' => [
......@@ -440,16 +445,20 @@ First we need to setup event handler, this can be done via configuration:
'app' => 'app.php',
'app/error' => 'error.php',
],
'on missingTranslation' => ['TranslationEventHandler', 'handleMissingTranslation']
'on missingTranslation' => ['app\components\TranslationEventHandler', 'handleMissingTranslation']
],
],
],
],
```
Now we need to implement own handler:
Now we need to implement our own event handler:
```php
<?php
namespace app\components;
use yii\i18n\MissingTranslationEvent;
class TranslationEventHandler
......@@ -460,22 +469,37 @@ class TranslationEventHandler
}
```
If [[yii\i18n\MissingTranslationEvent::translatedMessage]] is set by event handler it will be displayed as translation result.
If [[yii\i18n\MissingTranslationEvent::translatedMessage]] is set by the event handler it will be displayed as the translation result.
> Attention: each message source handles its missing translations separately. If you are using several message sources
and wish them treat missing translation in the same way, you should assign corresponding event handler to each of them.
> and wish them treat missing translation in the same way, you should assign corresponding event handler to each of them.
Views
-----
You can use i18n in your views to provide support for different languages. For example, if you have view `views/site/index.php` and
you want to create special case for russian language, you create `ru-RU` folder under the view path of current controller/widget and
put there file for russian language as follows `views/site/ru-RU/index.php`.
Instead of translating messages as described in the last section,
you can also use `i18n` in your views to provide support for different languages. For example, if you have a view `views/site/index.php` and
you want to create a special version for russian language of it, you create a `ru-RU` folder under the view path of the current controller/widget and
put the file for russian language as follows `views/site/ru-RU/index.php`. Yii will then load the file for the current language if it exists
and fall back to the original view file if none was found.
> **Note**: If language is specified as `en-US` and there are no corresponding views, Yii will try views under `en`
> before using original ones.
i18n Formatter
--------------
Formatting Number and Date values
---------------------------------
See the [data formatter section](output-formatter.md) for details.
Setting up your PHP environment <a name="setup-environment"></a>
-------------------------------
TDB
> Note that formatting may differ between different versions of the ICU library compiled with PHP and also based on the fact whether the
> [PHP intl extension](http://php.net/manual/en/book.intl.php) is installed or not. So to ensure your website works with the same output
> in all environments it is recommended to install the PHP intl extension in all environments and verify that the version of the ICU library
> is the same.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment