= Yii 2 Internationalization (i18n) =
== Configuration for Translated Views ==
Configure ''sourceLanguage'' and ''language'' (target language) in the application configuration file, such as ''@app/config/web.php'' or ''@common/config/main.php'':
[
//...
],
// set source language to be English
'sourceLanguage' => 'en-US',
// set target language to be Spanish (US)
//'language' => 'es-US',
// set target language to be Russian
'language' => 'ru-RU',
//...
];
Then translate the view and place it under its own locale folder. For example, when translating view ''@app/views/payment/view.php'', place it in ''@app/views/payment/ru-RU/view.php''.
== Configuration for Translated Messages ==
Edit configuration file to include i18n translations.
[
// ...
// set translations
'i18n' => [
'translations' => [
// Default Message Source
'*' => [
'class' => 'yii\i18n\PhpMessageSource'
],
// Yii Framework Message Source
// Place your adjusted translations to @app/messages//yii.php
'yii' => [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en-US',
'basePath' => '@app/messages'
],
// App Message Source
//'app*' => [
// 'class' => 'yii\i18n\PhpMessageSource',
// 'fileMap' => [
// 'app' => 'app.php',
// 'app/error' => 'error.php',
// ],
// 'on missingTranslation' => [
// 'app\components\TranslationEventHandler', 'handleMissingTranslation'
// ]
//],
],
],
],
// set source language to be English
'sourceLanguage' => 'en-US',
// set target language to be Spanish (US)
//'language' => 'es-US',
// ...
];
=== Generate i18n Config File ===
Generate the config file ''i18n.php'' in the config folder:
$ ./yii message/config @app/config/i18n.php
Customize the config file:
__DIR__ . DIRECTORY_SEPARATOR . '..',
// Root directory containing message translations.
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'messages',
// array, required, list of language codes that the extracted messages
// should be translated to. For example, ['zh-CN', 'de'].
'languages' => ['de','es','fr','pt'],
// string, the name of the function for translating messages.
// Defaults to 'Yii::t'. This is used as a mark to find the messages to be
// translated. You may use a string for single function name or an array for
// multiple function names.
'translator' => 'Yii::t',
// boolean, whether to sort messages by keys when merging new messages
// with the existing ones. Defaults to false, which means the new (untranslated)
// messages will be separated from the old (translated) ones.
'sort' => false,
// boolean, whether to remove messages that no longer appear in the source code.
// Defaults to false, which means each of these messages will be enclosed with a pair of '@@' marks.
'removeUnused' => false,
// array, list of patterns that specify which files (not directories) should be processed.
// If empty or not set, all files/directories will be processed.
// A path matches a pattern if it contains the pattern string at its end. For example,
// '/a/b' will match all files and directories ending with '/a/b';
// the '*.svn' will match all files and directories whose name ends with '.svn'.
// and the '.svn' will match all files and directories named exactly '.svn'.
// Note, the '/' characters in a pattern matches both '/' and '\'.
// See helpers/FileHelper::findFiles() description for more details on pattern matching rules.
'only' => ['*.php'],
// array, list of patterns that specify which files/directories should NOT be processed.
// If empty or not set, all files will be processed.
// Please refer to "except" for details about the patterns.
// If a file/directory matches both a pattern in "only" and "except", it will NOT be processed.
'except' => [
'.svn',
'.git',
'.gitignore',
'.gitkeep',
'.hgignore',
'.hgkeep',
'/messages',
'/vendor/kartik-v/yii2-detail-view/DetailView.php',
'/vendor/kartik-v',
],
// 'php' output format is for saving messages to php files.
'format' => 'php',
// boolean, whether the message file should be overwritten with the merged messages
'overwrite' => true,
/*
// 'db' output format is for saving messages to database.
'format' => 'db',
// Connection component to use. Optional.
'db' => 'db',
// Custom source message table. Optional.
// 'sourceMessageTable' => '{{%source_message}}',
// Custom name for translation message table. Optional.
// 'messageTable' => '{{%message}}',
*/
/*
// 'po' output format is for saving messages to gettext po files.
'format' => 'po',
// Root directory containing message translations.
'messagePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages',
// Name of the file that will be used for translations.
'catalog' => 'messages',
// boolean, whether the message file should be overwritten with the merged messages
'overwrite' => true,
*/
];
=== Extract i18n Strings from App ===
To get all the translatable strings into our ''@app/messages'' folder, run:
$ mkdir messages
$./yii message/extract @app/config/i18n.php
Now translate the strings in ''@app/messages/es/app.php'', ''@app/messages/es/frontend.php'', etc.:
/*
* NOTE: this file must be saved in UTF-8 encoding.
*
* Each array element represents the translation (value) of a message (key).
* If the value is empty, the message is considered as not translated.
*
* Messages that no longer need translation will have their translations
* enclosed between a pair of '@@' marks.
*/
return [
'About' => '',
'Contact' => '',
'Home' => '',
'Logout' => '',
'My Company' => '',
'Sign In' => '',
'Sign Up' => '',
'Status' => '',
//...
];
=== Models ===
In the models, all strings to be displayed need to include the ''Yii::t(...)'' notation. Eg:
class PaymentController extends Controller
{
// ...
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'message' => Yii::t('app', 'Message'),
'permissions' => Yii::t('app', 'Permissions'),
// ...
'created_at' => Yii::t('app', 'Created At'),
'updated_at' => Yii::t('app', 'Updated At'),
];
}
}
=== Controllers ===
In the controller, all string to be displayed need to include the ''Yii::t(...)'' notation. eg:
// Basic Messages
echo Yii::t('app', 'User List');
// Messages can contain parameter placeholders which will be replaced
// with the actual parameter values when calling Yii::t(). For example,
// the following message translation request would replace
// the {alias} placeholder in the original message with the actual alias value.
echo Yii::t('app', "Unable to view user ID {id}'s profile.", ['id' => $id]);
// Positional placeholders
$price = 100;
$count = 2;
$subtotal = 200;
echo \Yii::t('app', 'Price: {0}, Count: {1}, Subtotal: {2}', [$price, $count, $subtotal]);
echo \Yii::t('app', 'Price: {0}', $price);
See more formatting and placeholders: [[https://www.yiiframework.com/doc/guide/2.0/en/tutorial-i18n|Tutorial i18n]]
== Detecting Language Automatically ==
Create bootstrap code. For example, create file ''app\components\LanguageSelector'':
[
* // [
* // 'class' => 'app\components\LanguageSelector',
* // 'supportedLanguages' => ['en_US', 'ru_RU'],
* // ],
* // ],
* // // ...
* // ];
*/
namespace app\components;
use yii\base\BootstrapInterface;
class LanguageSelector implements BootstrapInterface
{
public $supportedLanguages = [];
public function bootstrap($app)
{
$preferredLanguage = $app->request->getPreferredLanguage($this->supportedLanguages);
$app->language = $preferredLanguage;
}
}
?>
Add bootstrap code in config file, such as ''@app/config/web.php'' or ''@common/config/main.php'':
$config = [
//...
];
$config['bootstrap'][] = [
'class' => 'app\components\LanguageSelector',
'supportedLanguages' => ['es_US', 'en_US'],
];
== References ==
* [[https://code.tutsplus.com/tutorials/how-to-program-with-yii2-localization-with-i18n--cms-23140|Tutsplus.com: Yii2 Localization with i18n]]
* [[http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html#view-translation|Yii2 Guide: i18n Tutorial]]
* [[http://code-epicenter.com/how-to-make-multilanguage-website-using-yii-framework|Yii1 Multi-language Website]]
* [[https://github.com/samdark/yii2-cookbook/blob/master/book/i18n-selecting-application-language.md|Yii2 Cookbook: i18n Selecting Application Language]]
* [[https://github.com/codemix/yii2-localeurls|Yii2-LocaleUrls Extension]]