本地化
📝 此頁面為 Laravel 官方文檔的繁體中文翻譯。查看原始英文版本
本地化
簡介
[!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
我們將在本文檔中討論管理翻譯字串的每種方法。
發佈語言檔案
預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果您希望自訂 Laravel 的語言檔案或建立自己的語言檔案,應該透過 lang:publish Artisan 命令來搭建 lang 目錄。lang:publish 命令將在您的應用程式中建立 lang 目錄,並發佈 Laravel 使用的預設語言檔案集:
php artisan lang:publish
配置語言環境
您應用程式的預設語言存儲在 config/app.php 配置檔案的 locale 配置選項中,通常使用 APP_LOCALE 環境變數來設定。您可以自由修改此值以滿足應用程式的需求。
您還可以配置一個「後備語言」,當預設語言不包含給定的翻譯字串時將使用該語言。與預設語言一樣,後備語言也在 config/app.php 配置檔案中配置,其值通常使用 APP_FALLBACK_LOCALE 環境變數來設定。
您可以使用 App 外觀提供的 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);
// ...
});
判斷當前語言環境
您可以使用 App 外觀上的 currentLocale 和 isLocale 方法來判斷當前語言環境或檢查語言環境是否為給定值:
use Illuminate\Support\Facades\App;
$locale = App::currentLocale();
if (App::isLocale('en')) {
// ...
}
複數化語言
您可以指示 Laravel 的「複數化器」(由 Eloquent 和框架的其他部分用於將單數字串轉換為複數字串)使用英語以外的語言。這可以透過在應用程式服務提供者的 boot 方法中呼叫 useLanguage 方法來完成。複數化器目前支援的語言有:french、norwegian-bokmal、portuguese、spanish 和 turkish:
use Illuminate\Support\Pluralizer;
/**
* 啟動任何應用程式服務。
*/
public function boot(): void
{
Pluralizer::useLanguage('spanish');
// ...
}
[!WARNING] 如果您自訂了複數化器的語言,應該明確定義 Eloquent 模型的表名。
定義翻譯字串
使用短鍵
通常,翻譯字串存儲在 lang 目錄中的檔案內。在此目錄中,應該為應用程式支援的每種語言設有一個子目錄。這是 Laravel 用於管理內建 Laravel 功能(如驗證錯誤訊息)的翻譯字串的方法:
/lang
/en
messages.php
/es
messages.php
所有語言檔案都返回一個帶有鍵的字串陣列。例如:
<?php
// lang/en/messages.php
return [
'welcome' => 'Welcome to our application!',
];
[!WARNING] 對於因地區而異的語言,您應該根據 ISO 15897 來命名語言目錄。例如,應該使用「en_GB」來表示英國英語,而不是「en-gb」。
使用翻譯字串作為鍵
對於具有大量可翻譯字串的應用程式,使用「短鍵」定義每個字串在視圖中引用鍵時可能會變得令人困惑,並且為應用程式支援的每個翻譯字串不斷發明鍵也很繁瑣。
為此,Laravel 還支援使用字串的「預設」翻譯作為鍵來定義翻譯字串。使用翻譯字串作為鍵的語言檔案以 JSON 檔案的形式存儲在 lang 目錄中。例如,如果您的應用程式有西班牙語翻譯,您應該建立一個 lang/es.json 檔案:
{
"I love programming.": "Me encanta programar."
}
鍵/檔案衝突
您不應定義與其他翻譯檔案名衝突的翻譯字串鍵。例如,在 nl/action.php 檔案存在但 nl.json 檔案不存在的情況下,為「NL」語言環境翻譯 __('Action') 將導致翻譯器返回 nl/action.php 的完整內容。
檢索翻譯字串
您可以使用 __ 輔助函數從語言檔案中檢索翻譯字串。如果您正在使用「短鍵」來定義翻譯字串,應該使用「點」記法將包含該鍵的檔案和鍵本身傳遞給 __ 函數。例如,讓我們從 lang/en/messages.php 語言檔案中檢索 welcome 翻譯字串:
echo __('messages.welcome');
如果指定的翻譯字串不存在,__ 函數將返回翻譯字串鍵。因此,使用上面的範例,如果翻譯字串不存在,__ 函數將返回 messages.welcome。
如果您正在使用預設翻譯字串作為翻譯鍵,應該將字串的預設翻譯傳遞給 __ 函數:
echo __('I love programming.');
同樣,如果翻譯字串不存在,__ 函數將返回它收到的翻譯字串鍵。
如果您正在使用 Blade 範本引擎,可以使用 {{ }} echo 語法來顯示翻譯字串:
{{ __('messages.welcome') }}
替換翻譯字串中的參數
如果您願意,可以在翻譯字串中定義佔位符。所有佔位符都以 : 為前綴。例如,您可以定義一個帶有佔位符名稱的歡迎訊息:
'welcome' => 'Welcome, :name',
要在檢索翻譯字串時替換佔位符,可以將替換陣列作為第二個參數傳遞給 __ 函數:
echo __('messages.welcome', ['name' => 'dayle']);
如果您的佔位符包含所有大寫字元,或者只有其第一個字母大寫,則翻譯後的值將相應地大寫:
'welcome' => 'Welcome, :NAME', // Welcome, DAYLE
'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle
物件替換格式
如果您嘗試提供一個物件作為翻譯佔位符,將呼叫該物件的 __toString 方法。__toString 方法是 PHP 的內建「魔法方法」之一。但是,有時您可能無法控制給定類別的 __toString 方法,例如當您正在互動的類別屬於第三方函式庫時。
在這些情況下,Laravel 允許您為該特定類型的物件註冊一個自訂格式處理器。為此,您應該呼叫翻譯器的 stringable 方法。stringable 方法接受一個閉包,該閉包應鍵入提示其負責格式化的物件類型。通常,stringable 方法應在應用程式的 AppServiceProvider 類別的 boot 方法中被呼叫:
use Illuminate\Support\Facades\Lang;
use Money\Money;
/**
* 啟動任何應用程式服務。
*/
public function boot(): void
{
Lang::stringable(function (Money $money) {
return $money->formatTo('en_GB');
});
}
複數化
複數化是一個複雜的問題,因為不同的語言有各種複雜的複數化規則;但是,Laravel 可以幫助您根據您定義的複數化規則以不同的方式翻譯字串。使用 | 字元,您可以區分字串的單數和複數形式:
'apples' => 'There is one apple|There are many apples',
當然,使用翻譯字串作為鍵時也支援複數化:
{
"There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas"
}
您甚至可以建立更複雜的複數化規則,為多個值範圍指定翻譯字串:
'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',
定義具有複數化選項的翻譯字串後,您可以使用 trans_choice 函數來檢索給定「數量」的行。在此範例中,由於數量大於一,因此返回翻譯字串的複數形式:
echo trans_choice('messages.apples', 10);
您還可以在複數化字串中定義佔位符屬性。可以透過將陣列作為第三個參數傳遞給 trans_choice 函數來替換這些佔位符:
'minutes_ago' => '{1} :value minute ago|[2,*] :value minutes ago',
echo trans_choice('time.minutes_ago', 5, ['value' => 5]);
如果您希望顯示傳遞給 trans_choice 函數的整數值,可以使用內建的 :count 佔位符:
'apples' => '{0} There are none|{1} There is one|[2,*] There are :count',
覆蓋套件語言檔案
某些套件可能附帶自己的語言檔案。與其更改套件的核心檔案來調整這些行,您可以透過將檔案放在 lang/vendor/{package}/{locale} 目錄中來覆蓋它們。
因此,例如,如果您需要覆蓋名為 skyrim/hearthfire 的套件中 messages.php 的英文翻譯字串,您應該在以下位置放置一個語言檔案:lang/vendor/hearthfire/en/messages.php。在此檔案中,您應該只定義您希望覆蓋的翻譯字串。您未覆蓋的任何翻譯字串仍將從套件的原始語言檔案中載入。