= 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]]