看板 Mesak
作者 標題 [PHP] YII2 繼承語言檔 (二)
時間 2016-03-01 Tue. 16:37:23
YII2 的語言檔是 Yii::t('Category Name', 'Word')
Category Name 主要是位置以及分類的判定 在 config 中 開啟 i18n
以我的進階版本作為範例。
'i18n' => [
'translations' => [
'bk.*' => [
'class' => 'yii\i18n\PhpMessageSource',
],
'fr.*' => [
'class' => 'yii\i18n\PhpMessageSource',
],
'yii' => [
'class' => 'yii\i18n\PhpMessageSource',
],
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
],
],
],
'translations' => [
'bk.*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@backend/messages'
],
'fr.*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@frontend/messages'
],
'yii' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@common/messages'
],
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@common/messages'
],
],
],
比如說我有一個 post 的 model , 就會使用 Yii::t('bk.model', 'Title')
系統自動會先載入 'yii\i18n\PhpMessageSource' ,並且使用 @backend/messages 資料夾下的 bk.model.php 來當語言檔來源
如果今天沒有定義到 'Title' 這個語言,系統就會直接輸出 'Title',如果有輸入,就會變成定義的語言
但是今天遇到一個狀況是需要重複使用到很多次的語言,比如說 常常會有 'created_at'、'updated_at' 這類定義欄位
如果都統一用語言檔就還好,但是就是這個但是,偶爾就是會有不同的翻譯出現,比如說 發文時間、建立時間、報名時間.....等等
這時候如果用 gii 建立出來的時候,要改變資料的話就會比較麻煩,一開始為了快速建立可能不會更動,變成每一個 語言分類都要建立一個一樣的資料然後指定給 預設的資料。
比如說 bk.model.php
return [
]
'created_at' => Yii::t('yii', 'created_at') ,
'updated_at' => Yii::t('yii', 'updated_at') ,
]
當然你有幾個語言分類就要建立幾次,有點顯得臃腫。
研究了一下 i18n 的做法,然後去修改一下 先修改 config
'i18n' => [
'translations' => [
'bk.*' => [
'class' => 'Mesak\i18n\PhpMessageSource',
],
'fr.*' => [
'class' => 'Mesak\i18n\PhpMessageSource',
],
'yii' => [
'class' => 'Mesak\i18n\PhpMessageSource'
],
'*' => [
'class' => 'Mesak\i18n\PhpMessageSource',
],
],
],
'translations' => [
'bk.*' => [
'basePath' => '@backend/messages',
'class' => 'Mesak\i18n\PhpMessageSource',
'sourceCategory' => 'yii'
],
'fr.*' => [
'basePath' => '@frontend/messages',
'class' => 'Mesak\i18n\PhpMessageSource',
'sourceCategory' => 'yii'
],
'yii' => [
'basePath' => '@common/messages',
'class' => 'Mesak\i18n\PhpMessageSource'
],
'*' => [
'basePath' => '@common/messages',
'class' => 'Mesak\i18n\PhpMessageSource',
],
],
],
將語言 class 改為自己的程式,增加一個 往上追加搜尋的語言分類標籤 :sourceCategory
要使用自己的 class 要先讓系統載入,進階版增加一個 classMap 到 common\config\bootstrap.php
Yii::$classMap['Mesak\i18n\PhpMessageSource'] = '@mesak/i18n/PhpMessageSource.php';
接著 建立 PhpMessageSource,如果自己有位置就放自己的位置吧
namespace Mesak\i18n;
use Yii;
class PhpMessageSource extends \yii\i18n\PhpMessageSource
{
public $sourceCategory;
public function translate($category, $message, $language)
{
if ($this->forceTranslation || $language !== $this->sourceLanguage) {
$string = $this->translateMessage($category, $message, $language);
if( $string === false && !empty($this->sourceCategory) )
{
}
return $string;
} else {
return false;
}
}
}
use Yii;
class PhpMessageSource extends \yii\i18n\PhpMessageSource
{
public $sourceCategory;
public function translate($category, $message, $language)
{
if ($this->forceTranslation || $language !== $this->sourceLanguage) {
$string = $this->translateMessage($category, $message, $language);
if( $string === false && !empty($this->sourceCategory) )
{
$string = Yii::t($this->sourceCategory, $message, $language);
}
return $string;
} else {
return false;
}
}
}
修改這兩串就可以了,現在 bk.model.php 語言檔可以把 'created_at'、'updated_at' 這類定義語言拿掉,只需要留下最後層的語言定義就可以了
如果載入語言 Yii::t('bk.model', 'Title')
會先到 bk.model.php 搜尋對應來源,如果找不到 'Title' 又有設定 追加搜尋的語言分類標籤 sourceCategory ,又會往上找尋目標語言分類的 對應來源,如果來源也有設定 追加搜尋的語言分類標籤 ,也會一直搜尋下去
所以要注意無限迴圈的問題,最後一層請不要有 追加搜尋的設定,以範例來說,'bk.model' 搜尋後 找不到就會去找 'yii' 的檔案
如果沒有就會回傳 原字串,這樣就可以解決語言檔設定重複字的狀況,又可以活動的支援自定義的語言檔。
--
Mesak Blog
http://mesak.tw
--
※ 作者: mesak 時間: 2016-03-01 16:37:23
※ 看板: Mesak 文章推薦值: 0 目前人氣: 0 累積人氣: 199
回列表(←)
分享