你可以指示 Laravel 的「複數化器」使用英語以外的語言,Eloquent 和框架的其他部分會使用它將單數字串轉換為複數字串。這可以透過在應用程式的某個 service provider 的 boot 方法中調用 useLanguage 方法來完成。複數化器目前支援的語言有:french、norwegian-bokmal、portuguese、spanish 和 turkish: - 設定地區 - 複數化語言
介紹 (Introduction)
[!NOTE] 預設情況下,Laravel 應用程式骨架不包含
lang目錄。如果你想自訂 Laravel 的語言檔案,你可以透過lang:publishArtisan 命令發布它們。
Laravel 的本地化功能提供了一種方便的方式來擷取各種語言的字串,讓你可以輕鬆地在應用程式中支援多種語言。
Laravel 提供兩種方式來管理翻譯字串。首先,語言字串可以儲存在應用程式的 lang 目錄中的檔案裡。在這個目錄中,可能會有應用程式支援的每種語言的子目錄。這是 Laravel 用於管理內建 Laravel 功能(如驗證錯誤訊息)的翻譯字串的方法:
/lang
/en
messages.php
/es
messages.php
或者,翻譯字串可以定義在放置於 lang 目錄中的 JSON 檔案裡。採用這種方法時,應用程式支援的每種語言在此目錄中都會有對應的 JSON 檔案。對於有大量可翻譯字串的應用程式,建議使用這種方法:
/lang
en.json
es.json
我們將在這份文件中討論每種管理翻譯字串的方法。
發布語言檔案 (Publishing The Language Files)
預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果你想自訂 Laravel 的語言檔案或建立你自己的語言檔案,你應該透過 lang:publish Artisan 命令建立 lang 目錄骨架。lang:publish 命令會在你的應用程式中建立 lang 目錄並發布 Laravel 使用的預設語言檔案集:
php artisan lang:publish
設定地區 (Configuring The Locale)
應用程式的預設語言儲存在 config/app.php 設定檔的 locale 設定選項中,通常使用 APP_LOCALE 環境變數設定。你可以自由修改這個值以適合你的應用程式需求。
你也可以設定一個「備用語言」,當預設語言不包含指定的翻譯字串時會使用它。像預設語言一樣,備用語言也在 config/app.php 設定檔中設定,其值通常使用 APP_FALLBACK_LOCALE 環境變數設定。
你可以使用 App facade 提供的 setLocale 方法在執行時修改單一 HTTP 請求的預設語言:
use Illuminate\Support\Facades\App;
Route::get('/greeting/{locale}', function (string $locale) {
if (! in_array($locale, ['en', 'es', 'fr'])) {
abort(400);
}
App::setLocale($locale);
// ...
});
判斷當前地區 (Determining The Current Locale)
你可以使用 App facade 上的 currentLocale 和 isLocale 方法來判斷當前地區或檢查地區是否為指定值:
use Illuminate\Support\Facades\App;
$locale = App::currentLocale();
if (App::isLocale('en')) {
// ...
}
複數化語言 (Pluralization Language)
你可以指示 Laravel 的「複數化器」使用英語以外的語言,Eloquent 和框架的其他部分會使用它將單數字串轉換為複數字串。這可以透過在應用程式的某個 service provider 的 boot 方法中調用 useLanguage 方法來完成。複數化器目前支援的語言有:french、norwegian-bokmal、portuguese、spanish 和 turkish:
use Illuminate\Support\Pluralizer;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Pluralizer::useLanguage('spanish');
// ...
}
[!WARNING] 如果你自訂了複數化器的語言,你應該明確定義你的 Eloquent model 的資料表名稱。
定義翻譯字串 (Defining Translation Strings)
使用短鍵 (Using Short Keys)
通常,翻譯字串儲存在 lang 目錄中的檔案裡。在這個目錄中,應該有應用程式支援的每種語言的子目錄。這是 Laravel 用於管理內建 Laravel 功能(如驗證錯誤訊息)的翻譯字串的方法:
/lang
/en
messages.php
/es
messages.php
所有語言檔案都回傳一個有鍵的字串陣列。例如:
<?php
// lang/en/messages.php
return [
'welcome' => '歡迎來到我們的應用程式!',
];
[!WARNING] 對於因地區而異的語言,你應該根據 ISO 15897 命名語言目錄。例如,英式英語應使用 "en_GB" 而非 "en-gb"。
使用翻譯字串作為鍵 (Using Translation Strings As Keys)
對於有大量可翻譯字串的應用程式,使用「短鍵」定義每個字串在視圖中參考鍵時會變得混亂,而且為應用程式支援的每個翻譯字串不斷發明鍵也很繁瑣。
因此,Laravel 也支援使用字串的「預設」翻譯作為鍵來定義翻譯字串。使用翻譯字串作為鍵的語言檔案會以 JSON 檔案的形式儲存在 lang 目錄中。例如,如果你的應用程式有西班牙語翻譯,你應該建立一個 lang/es.json 檔案:
{
"I love programming.": "Me encanta programar."
}
鍵 / 檔案衝突
你不應該定義與其他翻譯檔名衝突的翻譯字串鍵。例如,當 nl/action.php 檔案存在但 nl.json 檔案不存在時,為 "NL" 地區翻譯 __('Action') 會導致翻譯器回傳 nl/action.php 的全部內容。
擷取翻譯字串 (Retrieving Translation Strings)
你可以使用 __ 輔助函式從語言檔案中擷取翻譯字串。如果你使用「短鍵」來定義翻譯字串,你應該使用「點」語法將包含鍵的檔案和鍵本身傳遞給 __ 函式。例如,讓我們從 lang/en/messages.php 語言檔案中擷取 welcome 翻譯字串:
echo __('messages.welcome');
如果指定的翻譯字串不存在,__ 函式會回傳翻譯字串鍵。所以,使用上面的範例,如果翻譯字串不存在,__ 函式會回傳 messages.welcome。
如果你使用預設翻譯字串作為翻譯鍵,你應該將字串的預設翻譯傳遞給 __ 函式:
echo __('I love programming.');
同樣地,如果翻譯字串不存在,__ 函式會回傳它被給予的翻譯字串鍵。
如果你使用 Blade 模板引擎,你可以使用 {{ }} echo 語法來顯示翻譯字串:
{{ __('messages.welcome') }}
替換翻譯字串中的參數 (Replacing Parameters In Translation Strings)
如果你願意,你可以在翻譯字串中定義佔位符。所有佔位符都以 : 為前綴。例如,你可以定義一個帶有佔位符名稱的歡迎訊息:
'welcome' => '歡迎,:name',
要在擷取翻譯字串時替換佔位符,你可以將替換陣列作為第二個引數傳遞給 __ 函式:
echo __('messages.welcome', ['name' => 'dayle']);
如果你的佔位符包含全部大寫字母,或只有第一個字母大寫,翻譯值會相應地大寫:
'welcome' => '歡迎,:NAME', // 歡迎,DAYLE
'goodbye' => '再見,:Name', // 再見,Dayle
物件替換格式化 (Object Replacement Formatting)
如果你嘗試提供物件作為翻譯佔位符,物件的 __toString 方法會被調用。__toString 方法是 PHP 內建的「魔術方法」之一。然而,有時你可能無法控制給定類別的 __toString 方法,例如當你互動的類別屬於第三方函式庫時。
在這些情況下,Laravel 允許你為該特定類型的物件註冊自訂格式化處理器。為達成此目的,你應該調用翻譯器的 stringable 方法。stringable 方法接受一個閉包,該閉包應該類型提示它負責格式化的物件類型。通常,stringable 方法應該在應用程式的 AppServiceProvider 類別的 boot 方法中調用:
use Illuminate\Support\Facades\Lang;
use Money\Money;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Lang::stringable(function (Money $money) {
return $money->formatTo('en_GB');
});
}
複數化 (Pluralization)
複數化是一個複雜的問題,因為不同的語言有各種複雜的複數化規則;然而,Laravel 可以根據你定義的複數化規則以不同方式翻譯字串。使用 | 字元,你可以區分字串的單數和複數形式:
'apples' => '有一顆蘋果|有很多蘋果',
當然,使用翻譯字串作為鍵時也支援複數化:
{
"There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas"
}
你甚至可以建立更複雜的複數化規則,為多個值範圍指定翻譯字串:
'apples' => '{0} 沒有|[1,19] 有一些|[20,*] 有很多',
在定義了具有複數化選項的翻譯字串後,你可以使用 trans_choice 函式來擷取給定「計數」的行。在這個範例中,由於計數大於一,會回傳翻譯字串的複數形式:
echo trans_choice('messages.apples', 10);
你也可以在複數化字串中定義佔位符屬性。這些佔位符可以透過將陣列作為第三個引數傳遞給 trans_choice 函式來替換:
'minutes_ago' => '{1} :value 分鐘前|[2,*] :value 分鐘前',
echo trans_choice('time.minutes_ago', 5, ['value' => 5]);
如果你想顯示傳遞給 trans_choice 函式的整數值,你可以使用內建的 :count 佔位符:
'apples' => '{0} 沒有|{1} 有一顆|[2,*] 有 :count 顆',
覆寫套件語言檔案 (Overriding Package Language Files)
有些套件可能會隨附自己的語言檔案。與其更改套件的核心檔案來調整這些行,你可以透過在 lang/vendor/{package}/{locale} 目錄中放置檔案來覆寫它們。
因此,例如,如果你需要覆寫名為 skyrim/hearthfire 的套件的 messages.php 中的英語翻譯字串,你應該在 lang/vendor/hearthfire/en/messages.php 放置一個語言檔案。在這個檔案中,你應該只定義你想要覆寫的翻譯字串。任何你沒有覆寫的翻譯字串仍然會從套件的原始語言檔案中載入。