顯示廣告
隱藏 ✕
看板 Mesak
作者 mesak (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',
               
	
'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.*' => [
               
	
'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) )
            {
           
	
$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 
分享網址: 複製 已複製
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇