本地化
簡介
預設情況下,Laravel 應用程式骨架不包含 lang
目錄。如果您想要自訂 Laravel 的語言檔案,可以使用 lang:publish
Artisan 命令發佈它們。
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
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); // ...});
判斷目前的語系
您可以使用 App
Facade 上的 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; /** * Bootstrap any application services. */public function boot(): void{ Pluralizer::useLanguage('spanish'); // ...}
如果您自訂複數化程式的語言,您應該明確定義 Eloquent 模型的表格名稱。
定義翻譯字串
使用短鍵
通常,翻譯字串會儲存在 lang
目錄中的檔案中。在此目錄中,應為應用程式支援的每種語言建立子目錄。這是 Laravel 用於管理內建 Laravel 功能(例如驗證錯誤訊息)的翻譯字串的方法。
/lang /en messages.php /es messages.php
所有語言檔案都會傳回鍵值字串陣列。例如:
<?php // lang/en/messages.php return [ 'welcome' => 'Welcome to our application!',];
對於因地區而異的語言,您應該依照 ISO 15897 命名語言目錄。例如,英國英語應使用「en_GB」而不是「en-gb」。
使用翻譯字串作為鍵
對於具有大量可翻譯字串的應用程式,當在視圖中引用鍵時,使用「短鍵」定義每個字串可能會令人困惑,並且不斷為應用程式支援的每個翻譯字串發明鍵也很麻煩。
因此,Laravel 也支援使用字串的「預設」翻譯作為鍵來定義翻譯字串。使用翻譯字串作為鍵的語言檔案會以 JSON 檔案的形式儲存在 lang
目錄中。例如,如果您的應用程式有西班牙語翻譯,您應該建立一個 lang/es.json
檔案
{ "I love programming.": "Me encanta programar."}
鍵 / 檔案衝突
您不應定義與其他翻譯檔案名稱衝突的翻譯字串鍵。例如,為「NL」語系翻譯 __('Action')
,而 nl/action.php
檔案存在,但 nl.json
檔案不存在,會導致翻譯器傳回 nl/action.php
的完整內容。
擷取翻譯字串
您可以使用 __
輔助函式從語言檔案擷取翻譯字串。如果您使用「短鍵」定義翻譯字串,您應該使用「點」語法將包含鍵的檔案和鍵本身傳遞給 __
函式。例如,讓我們從 lang/en/messages.php
語言檔案擷取 welcome
翻譯字串
echo __('messages.welcome');
如果指定的翻譯字串不存在,__
函式將會傳回翻譯字串鍵。因此,使用上面的範例,如果翻譯字串不存在,__
函式會傳回 messages.welcome
。
如果您使用預設翻譯字串作為翻譯鍵,您應該將字串的預設翻譯傳遞給 __
函式;
echo __('I love programming.');
同樣地,如果翻譯字串不存在,__
函式將會傳回所給的翻譯字串鍵。
如果您使用 Blade 範本引擎,您可以使用 {{ }}
輸出語法來顯示翻譯字串。
{{ __('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; /** * Bootstrap any application services. */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
函式來檢索給定「計數」的行。在這個例子中,由於計數大於 1,因此會回傳翻譯字串的複數形式。
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
。在此檔案中,您只需定義您想要覆寫的翻譯字串。任何您未覆寫的翻譯字串仍會從套件的原始語言檔案載入。