例子
Yii:t()調用語言包的具體用法如下:
首先,假設我們有一個語言包文件:/protected/message/zh_cn/lang.php
文件內容如下:
<?php
return array(
'My Name'=>'我的名字',
);
?>
我們可以在view中這樣調用:
<?php echo Yii::t('lang','My Name'); ?>
在config/main.php 里加上 :'language' => 'zh_cn',
顯示結果就是:漢字:我的名字。
國際化
國際化(I18N)指軟件應用設計成無須改動引擎即可應用於不同語言和地區的過程。對於 web 應用,這點特別重要,因爲潛在用戶是全球範圍的。
地區和語言
在 Yii 應用中定義了兩個語言屬性:[[yii\base\Application::$sourceLanguage|source language]]和[[yii\base\Application::$language|target language]]。源語言是應用消息原始編寫語言:
echo \Yii::t('app', 'I am a message!');
目標語言是當前使用的語言,在應用配置中如下定義:提示:默認是英語,推薦不要更改。原因是人們翻譯英語到其他語言比非英語翻譯到其他語言更容易。
return [
'id' => 'applicationID',
'basePath' => dirname(__DIR__),
'language' => 'ru-RU' // ← 在這裏!
]
格式是 ll-CC
,其中 ll
是語言的兩個或三個小寫字母代碼,根據ISO-639分配確定,而 CC
是國家代碼,根據ISO-3166分配確定。然後就能容易地實時更改:
如果沒有 ru-RU
翻譯文件,Yii 將在提示失敗前嘗試查找 ru
翻譯文件。
注意:你能更進一步地自定義指定語言的細節as documented in ICU project.
消息翻譯
基礎
Yii 基礎消息翻譯在基本的變換工作中無須使用其他 PHP 擴展。它要做的只是查找從源語言翻譯到目標語言的消息翻譯文件。消息以\Yii::t
方法的第二個參數來指定:
echo \Yii::t('app', 'This is a string to translate!');
'components' => [
// ...
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
//'basePath' => '@app/messages',
//'sourceLanguage' => 'en',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',
],
],
],
],
],
Yii 將嘗試從定義在 i18n
組件配置中的消息源加載適當的翻譯:
以上 app*
指定了該消息源處理哪些類別的消息。這個例子中我們處理以 app
開頭的所有消息。你也可以指定缺省翻譯,更多消息請參考i18n 示例.
class
定義使用哪個消息源。以下消息源是可用的:
- PhpMessageSource 使用 PHP 文件保存
- GettextMessageSource 使用 GNU Gettext MO 或 PO 文件保存
- DbMessageSource 使用數據庫保存
basePath
定義當前使用消息源在哪裏保存消息。該例中保存在應用的 messages
目錄。使用數據庫保存的情況要跳過這個選項。
sourceLanguage
定義 \Yii::t
第二個參數使用的語言。如未定義,將使用應用的代碼語言。
fileMap
在PhpMessageSource
使用時定義指定在 \Yii::t()
第一個參數的消息類別如何映射到文件。該例中我們定義了兩個類別 app
和 app/error
。
依靠BasePath/messages/LanguageID/CategoryName.php
這樣約定好的翻譯文件格式可省略配置 fileMap
。
命名佔位符
可以添加參數到翻譯消息,翻譯後這些參數將被對應的值替換。格式是使用大括號包圍參數名,如下所示:
$username = 'Alexander';
echo \Yii::t('app', 'Hello, {username}!', [
'username' => $username,
]);
位置佔位符注意給參數賦值沒有大括號。
$sum = 42;
echo \Yii::t('app', 'Balance: {0}', $sum);
高級佔位符格式提示:要努力保持消息字符串有意義和避免使用太多位置參數。記住翻譯者只有源字符串,所以每個佔位符替換什麼必須是清晰明確的。
要使用高級功能需要安裝和啓用 intl PHP 擴展。安裝並啓用這個擴展後就能夠對佔位符使用擴展語法。可以是默認設置的縮寫形式{placeholderName, argumentType}
,也可以是允許指定格式風格的完整形式 {placeholderName, argumentType, argumentStyle}
。
完整參考請看available at ICU website。但它有點晦澀,我們在下面提供自己的參考。
數字
$sum = 42;
echo \Yii::t('app', 'Balance: {0, number}', $sum);
$sum = 42;
echo \Yii::t('app', 'Balance: {0, number, currency}', $sum);
你可以指定內置格式風格 (integer
, currency
, percent
)的其中一個:
或指定自定義格式:
$sum = 42;
echo \Yii::t('app', 'Balance: {0, number, ,000,000000}', $sum);
日期格式參考。
echo \Yii::t('app', 'Today is {0, date}', time());
echo \Yii::t('app', 'Today is {0, date, short}', time());
內置格式有 (short
, medium
, long
, full
):
自定義格式:
echo \Yii::t('app', 'Today is {0, date, YYYY-MM-dd}', time());
時間格式參考。
echo \Yii::t('app', 'It is {0, time}', time());
echo \Yii::t('app', 'It is {0, time, short}', time());
內置格式 (short
, medium
, long
, full
):
自定義格式:
echo \Yii::t('app', 'It is {0, date, HH:mm}', time());
拼出格式參考。
echo \Yii::t('app', '{n,number} is spelled as {n, spellout}', ['n' => 42]);
echo \Yii::t('app', 'You are {n, ordinal} visitor here!', ['n' => 42]);
序數
將輸出 "You are 42nd visitor here!"。
期間
echo \Yii::t('app', 'You are here for {n, duration} already!', ['n' => 47]);
複數將輸出 "You are here for 47 sec. already!"。
不同語言的複數表現形式不同。有些規則非常複雜,所以非常方便,已提供的功能不需要指定轉化規則。相反它只需要在指定的位置輸入轉化好的單詞即可。
echo \Yii::t('app', 'There {n, plural, =0{are no cats} =1{is one cat} other{are # cats}}!', ['n'=> 0]);
在以上的複數規則參數, =0
指恰好等於零, =1
指恰好是一個,而 other
是此外的所有數字。#
將用 n
參數值替換。但不是所有語言都像英語這麼簡單,如俄語的例子:將輸出 "There are no cats!"。
1 |
|
以上要提出的是 =1
精確匹配 n = 1
但 one
匹配 21
或 101
。
注意如果使用兩次佔位符,一次用來表示複數而另一處要用來表示數字,否則將會輸出 "Inconsistent types declared for an argument: U_ARGUMENT_TYPE_MISMATCH" 錯誤:
1 |
|
瞭解你的語言要用哪個轉化形式可以參考rules reference at unicode.org。
選集
可以基於關鍵詞挑選短語,這種例子的格式指定了怎樣映射關鍵詞到短信並提供了默認短語。
echo \Yii::t('app', '{name} is {gender} and {gender, select, female{she} male{he} other{it}} loves Yii!', [
'name' => 'Snoopy',
'gender' => 'dog',
]);
在表達式中 female
和 male
都是可選值,而 other
處理那些不匹配前兩者的值。大括號內的字符串是子表達式所以可以是一個字符串也可以是字符串和佔位符。將輸出 "Snoopy is dog and it loves Yii!".
指定默認翻譯
可以指定默認翻譯作爲回調函數用於某些不需要匹配其他翻譯的類別。該翻譯要用 *
標記。要做到這一點需要添加以下代碼到配置文件( yii2-basic
應用的話是 web.php
):
//配置 i18n 組件
'i18n' => [
'translations' => [
'*' => [
'class' => 'yii\i18n\PhpMessageSource'
],
],
],
echo Yii::t('not_specified_category', 'message from unspecified category');
現在無須逐個配置就能使用類別,這和 Yii 1.1 行爲是類似的。類別的消息將從默認翻譯根路徑( basePath
)即@app/messages
下的文件加載:
消息將從 @app/messages/<LanguageCode>/not_specified_category.php
加載。
翻譯小部件消息
對小部件也使用相同規則,如:
<?php
namespace app\widgets\menu;
use yii\base\Widget;
use Yii;
class Menu extends Widget
{
public function init()
{
parent::init();
$this->registerTranslations();
}
public function registerTranslations()
{
$i18n = Yii::$app->i18n;
$i18n->translations['widgets/menu/*'] = [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en',
'basePath' => '@app/widgets/menu/messages',
'fileMap' => [
'widgets/menu/messages' => 'messages.php',
],
];
}
public function run()
{
echo $this->render('index');
}
public static function t($category, $message, $params = [], $language = null)
{
return Yii::t('widgets/menu/' . $category, $message, $params, $language);
}
}
注意:小部件也可使用 i18n 視圖,規則和它們應用在控制器上是一樣的。要省略 fileMap
設置,只要簡單地遵循類別和同名文件的映射約定並直接使用 Menu::t('messages', 'new messages {messages}', ['{messages}' => 10])
即可。
翻譯框架消息
有時你想要爲你的應用校正默認的框架消息翻譯文件,可以如下配置i18n
組件:
'components' => [
'i18n' => [
'translations' => [
'yii' => [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en',
'basePath' => '/path/to/my/message/files'
],
],
],
],
視圖現在你可以在 /path/to/my/message/files
放入已調整過的翻譯文件了。
可以在視圖使用 i18n 來支持不同語言。例如,給視圖 views/site/index.php
創建俄語版本,就要在當前控制器/小部件的視圖路徑下創建 ru-RU
文件夾並放入俄語版本的視圖文件 views/site/ru-RU/index.php
。
注意:如果指定的語言爲
en-US
且沒有對應的視圖, Yii 將在使用原始視圖文件前查找en
下的視圖文件。
i18n 格式器
i18n 格式器組件是格式器的本地化版本,支持基於當前時區的日期、時間和數字的格式化。要使用格式器須配置格式器應用組件如下:
return [
// ...
'components' => [
'formatter' => [
'class' => 'yii\i18n\Formatter',
],
],
];
注意要使用 i18n 格式器先要安裝和啓用intl PHP 擴展。配置組件後就能用 Yii::$app->formatter
連接格式器了。
要了解格式器方法請參考它的 API 文檔:[[yii\i18n\Formatter]]。