このページで達成すること
パッケージのメッセージを多言語で配布し、利用アプリケーションが必要な文言だけを変更できるようにします。翻訳キー・プレースホルダーを公開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に流用しても、この場所は自動で読まれません。- アプリケーションの
lang/ja.jsonへパッケージのJSONをpublishes()しても、ファイル内容はマージされません。既存翻訳を壊さないよう、必要なキーだけを利用者が追加する手順を案内します。
Translator::get() はJSONの完全一致キーを先に調べるため、JSONに courier::messages.delivery.queued のようなキーを定義するとPHP側より優先されます。通常は文章キーとPHP形式のキーを混在させない方針にします。
公開済み翻訳を壊さずに更新する
PHP翻訳を一括公開したい利用者には、対象を絞ったコマンドを案内できます。- キーと名前空間を維持する — キーの削除・移動は、利用者の
__()呼び出しと上書き先に影響します。新しいキーを追加し、旧キーを残す移行期間を検討します。 - プレースホルダーを維持する —
:nameを:recipientに変えると、呼び出し側の置換配列も変更が必要です。翻訳ファイルだけの修正と考えないようにします。 - 公開済みファイルを差分確認する — 利用者の上書きと新しいデフォルトを比較します。不要になった上書きキーを削除すると、パッケージの値に戻せます。
- 無条件の再公開を避ける —
--forceによる再公開は利用者のカスタマイズを上書きします。JSONをアプリケーションのファイルへコピーする設計では、他の翻訳まで失う可能性があります。 - 常駐プロセスで確認する —
Translator::load()は名前空間・グループ・言語ごとの配列をインスタンス内に保持します。既に読み込み済みのTranslatorが残るプロセスでは、ファイル変更だけで再読込されるとは限りません。運用に応じてワーカー等を再起動します。
利用アプリケーションで確認する項目
サービスプロバイダーを登録した検証用アプリケーションで、次の組み合わせを確認します。パッケージ内のテスト環境構築はパッケージのテストを参照してください。
読み込み後に上書きファイルを作るテストでは、Translatorの既存の読み込み結果が影響しないようにします。ファイルを先に用意してから取得するか、ケースごとに新しいアプリケーションインスタンスを使って確認します。
参照した一次情報
公式ドキュメントは最新のデフォルトブランチ13.x、内部実装は参照時点の最新リリース v13.35.0 を確認しています。