本頁要達成的目標
以多語言發布套件的訊息,讓使用端應用程式只需變更必要的文字。並整理如何將翻譯鍵與預留位置視為公開 API,以及在套件更新時保留自訂內容的方法。 在地化說明應用程式中的基本操作,Laravel 套件開發說明註冊與公開的基礎。本頁則深入 Laravel 13 的ServiceProvider、FileLoader、Translator 的實作。
loadTranslationsFrom() 是註冊載入來源,publishes() 是註冊檔案的複製目的地。使用者不必為了使用翻譯而一定要執行 vendor:publish。以命名空間發布 PHP 翻譯
若要擁有套件專屬的鍵,請使用 PHP 陣列格式與命名空間。以下是名為Acme\Courier 的套件範例。
lang/ja/messages.php 準備日文的預設值。
lang/en/messages.php 也準備作為備援的英文。
boot() 中註冊載入與選用的公開。
ja,這與本文件網站 URL 所使用的 jp 不同。
courier 是 loadTranslationsFrom() 的第 2 個參數,並不會依 Composer 的套件名稱自動決定。
PHP 翻譯不會整個取代檔案
在使用端應用程式中,若使用標準語言目錄,只需在lang/vendor/courier/ja/messages.php 寫入要變更的鍵。即使變更了語言目錄,也使用 $this->app->langPath('vendor/courier') 底下的位置。
queued 會改變,failed 則使用套件的日文翻譯。
FileLoader 的載入順序
ServiceProvider::loadTranslationsFrom() 會在 Translator 解析後註冊命名空間。實際取得檔案則是在請求翻譯時才進行。
FileLoader::loadNamespaced() 會載入已註冊套件的語言檔,並將該陣列傳給 loadNamespaceOverrides()。接著讀取載入器各語言路徑中的 vendor/{namespace}/{locale}/{group}.php,並以 array_replace_recursive() 取代。
標準的 TranslationServiceProvider 會依序將框架的語言路徑與應用程式的語言路徑傳給載入器。即使有擴充功能註冊了額外路徑,之後載入的覆寫陣列也會優先使用相同的鍵。
JSON 翻譯沒有套件專屬的命名空間
以句子作為鍵的 JSON 翻譯,請以下列方式註冊目錄。這是與前述 PHP 翻譯不同的另一種選擇。lang/ja.json 範例如下。
loadJsonTranslationsFrom() 沒有命名空間參數。已註冊的 JSON 翻譯會與其他套件及應用程式共用相同的鍵空間。
JSON 的覆寫位置是應用程式的 ja.json
FileLoader::loadJsonPaths() 會先讀取已註冊的 JSON 路徑,再讀取一般的語言路徑,並進行 array_merge()。在標準設定中,應用程式 lang/ja.json 中相同的字串鍵會覆寫套件的值。
- 若多個套件使用相同的字串鍵,之後載入的 JSON 值會優先。請避免依賴提供者順序的設計。
lang/vendor/courier/ja.json不是標準 JSON 載入器的覆寫位置。即使將 PHP 用的公開設定直接沿用於 JSON,這個位置也不會被自動讀取。- 即使以
publishes()將套件的 JSON 公開到應用程式的lang/ja.json,檔案內容也不會被合併。為了不破壞既有翻譯,請引導使用者只新增必要的鍵。
Translator::get() 會先檢查 JSON 的完全相符鍵,若在 JSON 中定義 courier::messages.delivery.queued 這類鍵,將會優先於 PHP 端。通常應採取不混用句子鍵與 PHP 格式鍵的方針。
在不破壞已公開翻譯的情況下更新
對於想一次公開 PHP 翻譯的使用者,可以引導他們使用縮小對象範圍的指令。- 維持鍵與命名空間 — 刪除或移動鍵會影響使用者的
__()呼叫與覆寫位置。請考慮新增鍵並保留舊鍵的過渡期間。 - 維持預留位置 — 將
:name改為:recipient時,呼叫端的取代陣列也需要變更。請不要將其視為只修改翻譯檔。 - 比對已公開檔案的差異 — 比較使用者的覆寫與新的預設值。刪除不再需要的覆寫鍵,即可恢復為套件的值。
- 避免無條件重新公開 — 以
--force重新公開會覆寫使用者的自訂內容。在將 JSON 複製到應用程式檔案的設計中,可能連其他翻譯都會遺失。 - 在常駐程序中確認 —
Translator::load()會在實例內保存每個命名空間、群組與語言的陣列。在仍保留已載入 Translator 的程序中,僅變更檔案不一定會重新載入。請依維運方式重新啟動 worker 等。
在使用端應用程式中確認的項目
在已註冊服務提供者的驗證用應用程式中,確認下列組合。套件內的測試環境建置請參閱以 Orchestra Testbench 測試 Laravel 套件。
在載入後才建立覆寫檔案的測試中,請避免受到 Translator 既有載入結果的影響。可先準備好檔案再取得,或在每個案例中使用新的應用程式實例進行確認。
參考的一手資料
官方文件確認的是最新的預設分支13.x,內部實作確認的是參考當時的最新版本 v13.35.0。