國際化功能一般很少用到,但作為學習,還是有必要接觸一下。
國際化最常用到的方法是Yii::t,官方文件如下
t() public static method Translates a message to the specified language. This is a shortcut method of yii\i18n\I18N::translate(). The translation will be conducted according to the message category and the target language will be used. 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:
[code]$username = 'Alexander'; echo \Yii::t('app', 'Hello, {username}!', ['username' => $username]);
Further formatting of message parameters is supported using the PHPintl extensions message formatter. See yii\i18n\I18N::translate() formore details. public static stringt ($category, $message, $params = [],$language = null ) $category string The message category. $message string The message to be translated. $params array The parameters that will be used to replace the corresponding placeholders in the message. $language string The language code (e.g.en-US,en).If this is null, the current application language will be used. return string The translated message.
參數有4個,但常用到的是前兩個。
第一個是組別,組別的定義放在config/main-local.php下。
Yii2預設用的是英文(en-US),現在加入中文支援(zh-CN)
在component下新增如下區塊
'components' => [ ... 'i18n' => [ 'translations' => [ 'common' => [ 'class' => 'yii\i18n\PhpMessageSource', 'basePath' => '@common/messages', 'fileMap' => [ 'common' => 'common.php', ], ], ], ], ... ],
這段程式碼定義了一個名為common的組別,解析翻譯文件使用的是預設的類別yiii18nPhpMessageSource,翻譯檔案放置在common/messages下,翻譯檔案是common.php。
根據配置,建立如下的目錄結構
翻譯文件以數組的方式組織的,內容如下
<?php return [ 'Signup' => '注册', 'Login' => '登陆', 'Logout' => '登出', 'Home' => '首页', 'Contact' => '反馈', 'About' => '关于', ];
然後我們在layouts文件裡做翻譯,在/views/layouts/main.
然後我們在layouts文件裡做翻譯,在/views/layouts/main.php裡修改如下:$menuItems = [ //['label' => 'Home', 'url' => ['/site/index']], //['label' => 'About', 'url' => ['/site/about']], //['label' => 'Contact', 'url' => ['/site/contact']], ['label' => \Yii::t('common', 'Home'), 'url' => ['/site/index']], ['label' => \Yii::t('common', 'About'), 'url' => ['/site/about']], ['label' => \Yii::t('common', 'Contact'), 'url' => ['/site/contact']], ];
究原因,是因為網站的根語言還是en-US,需要配置為zh-CN。
<?php return [ 'language' => 'zh-CN', ... ];
可以看到翻譯已經生效。
但用Yii::t方法的主要原因是要實現多語言,如果只是顯示一種語言,不如做hardcode(yii2框架實際做的也是hardcode的語言顯示)
yii2沒有提供現成的切換語言的控件,需要我們自己開發一個。
實作參考http://www.yiiframework.com/wiki/294/seo-conform-multilingual-urls-language-selector-widget-i18n/,並做了適度的簡化,不做seo方面的考慮。
實現的主要想法是把使用者選擇的語言儲存到cookie中,每次使用者造訪頁面前,將語言設定為cookie中的值。為什麼需要每次設定語言,原因如下
Note: If we don't set Yii::app()->language explicitly for each request, it will be equal to its default value set in the confg file. If it is not set in the config file, it will be equal to the value Yii::app()->sourceLanguage, which defaults to 'en_us'.
大概意思是如果不每次進行設值的話,系統將自己採用默認語言,一般是英語。
<?php return [ 'language' => 'zh-CN', 'components' => [ ... ], 'params' => [ 'availableLanguages' => [ 'zh-CN' => ['img' => 'image/zh.png', 'desc' => '中文'], 'en-US' => ['img' => 'image/en.png', 'desc' => 'English'], ], ], ... ];
<?php namespace common\widgets; use Yii; use yii\helpers\Html; use yii\helpers\Url; class LanguageSelector { public static function getMenu() { $lang = Yii::$app->language; $avLang = Yii::$app->params['availableLanguages']; $isMatch = false; foreach ($avLang as $key => $value) { if($key == $lang) { $tag = LanguageSelector::buildImgTag($value['img'], $value['desc']); $isMatch = true; } } if(!$isMatch) { $tag = LanguageSelector::buildImgTag($avLang[0]['img'], $avLang[0]['desc']); } $return = [ 'label' => $tag, 'items' => LanguageSelector::buildMenuItems($avLang), ]; return $return; } private static function buildImgTag($src, $desc) { return '<img src="' . $src . '" alt="' . $desc . '">'; } private static function buildMenuItems($langs) { foreach ($langs as $key => $value) { $link = Html::a(LanguageSelector::buildImgTag($value['img'], $value['desc']) . ' ' . $value['desc'], Url::home(), [ 'title' => LanguageSelector::buildImgTag($value['img'], $value['desc']) . ' ' . $value['desc'], 'onclick'=>" $.ajax({ type :'POST', cache : false, url : '" . Url::toRoute("ajax/lang") . "', data: { _lang : '" . $key . "' }, success : function(response) { window.location.reload(); } });return false;", ]); $menuItems[] = '<li>' . $link . '</li>'; } return $menuItems; } }
<?php namespace frontend\controllers; use Yii; use yii\web\Controller; use common\components\SelectLanguageBehavior; use yii\web\cookie; class AjaxController extends Controller { public $layout = false; public function actionLang() { if (isset($_POST['_lang'])) { $lang = SelectLanguageBehavior::getSelectedLanguage($_POST['_lang']); Yii::$app->language = $lang; $cookie = new cookie([ 'name' => '_lang', 'value' => $lang, ] ); $cookie->expire = time() + (60*60*24*365); // (1 year) Yii::$app->response->cookies->add($cookie); } return "success"; } }
<?php namespace common\components; use yii\base\Application; use yii\base\Behavior; use yii\web\cookie; use Yii; class SelectLanguageBehavior extends Behavior { public function events() { return [ Application::EVENT_BEFORE_REQUEST => 'beforeRequest', ]; } public function beforeRequest($event) { $app = Yii::$app; $lang = SelectLanguageBehavior::getSelectedLanguage(Yii::$app->request->cookies->getValue('_lang')); $app->language = $lang; } public static function getSelectedLanguage($val) { $langs = Yii::$app->params['availableLanguages']; foreach ($langs as $key=>$value) { if($val == $key) { return $val; } } return key($langs); } }
<?php return [ 'language' => 'zh-CN', 'components' => [ ... ], ... 'as beginRequest' => [ 'class' => 'common\components\SelectLanguageBehavior', ], ];
... if (Yii::$app->user->isGuest) { $menuItems[] = ['label' => Yii::t('common', 'Signup'), 'url' => ['/site/signup']]; $menuItems[] = ['label' => Yii::t('common', 'Login'), 'url' => ['/site/login']]; } else { $menuItems[] = [ 'label' => Yii::t('common', 'Logout') . ' (' . Yii::$app->user->identity->username . ')', 'url' => ['/site/logout'], 'linkOptions' => ['data-method' => 'post'] ]; } // add this line $menuItems[] = \common\widgets\LanguageSelector::getMenu(); echo Nav::widget([ 'options' => [ 'class' => 'navbar-nav navbar-right', ], 'items' => $menuItems, // add this line 'encodeLabels' => false, ]); ...
以上就是Yii2 framework學習筆記(三) -- 語言與國際化的內容,更多相關內容請關注PHP中文網(www.php.cn)!