跳到內容

本地化

簡介

預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果您想要自訂 Laravel 的語言檔案,您可以透過 lang:publish Artisan 命令發佈它們。

Laravel 的本地化功能提供了一種便捷的方式來檢索各種語言的字串,讓您可以輕鬆地在您的應用程式中支援多種語言。

Laravel 提供了兩種管理翻譯字串的方式。首先,語言字串可以儲存在應用程式的 lang 目錄中的檔案中。在這個目錄中,可以有應用程式支援的每種語言的子目錄。這是 Laravel 用於管理內建 Laravel 功能(例如驗證錯誤訊息)的翻譯字串的方法

1/lang
2 /en
3 messages.php
4 /es
5 messages.php

或者,翻譯字串可以定義在放置在 lang 目錄中的 JSON 檔案中。當採用這種方法時,您的應用程式支援的每種語言都會在這個目錄中有一個對應的 JSON 檔案。對於有大量可翻譯字串的應用程式,建議使用這種方法

1/lang
2 en.json
3 es.json

我們將在本文件中討論管理翻譯字串的每種方法。

發佈語言檔案

預設情況下,Laravel 應用程式骨架不包含 lang 目錄。如果您想要自訂 Laravel 的語言檔案或建立您自己的檔案,您應該透過 lang:publish Artisan 命令建立 lang 目錄的骨架。lang:publish 命令將在您的應用程式中建立 lang 目錄,並發佈 Laravel 使用的預設語言檔案集

1php artisan lang:publish

設定語系

您的應用程式的預設語言儲存在 config/app.php 設定檔的 locale 設定選項中,這通常使用 APP_LOCALE 環境變數設定。您可以自由修改此值以符合您的應用程式的需求。

您還可以設定「後備語言」,當預設語言不包含給定的翻譯字串時,將使用該語言。與預設語言一樣,後備語言也在 config/app.php 設定檔中設定,其值通常使用 APP_FALLBACK_LOCALE 環境變數設定。

您可以使用 App facade 提供的 setLocale 方法,在運行時修改單個 HTTP 請求的預設語言

1use Illuminate\Support\Facades\App;
2 
3Route::get('/greeting/{locale}', function (string $locale) {
4 if (! in_array($locale, ['en', 'es', 'fr'])) {
5 abort(400);
6 }
7 
8 App::setLocale($locale);
9 
10 // ...
11});

判斷目前的語系

您可以使用 App facade 上的 currentLocaleisLocale 方法來判斷目前的語系或檢查語系是否為給定值

1use Illuminate\Support\Facades\App;
2 
3$locale = App::currentLocale();
4 
5if (App::isLocale('en')) {
6 // ...
7}

複數化語言

您可以指示 Laravel 的「複數化器」(Eloquent 和框架的其他部分使用它將單數字串轉換為複數字串)使用英語以外的語言。這可以透過在應用程式的其中一個服務提供者的 boot 方法中調用 useLanguage 方法來完成。複數化器目前支援的語言有:frenchnorwegian-bokmalportuguesespanishturkish

1use Illuminate\Support\Pluralizer;
2 
3/**
4 * Bootstrap any application services.
5 */
6public function boot(): void
7{
8 Pluralizer::useLanguage('spanish');
9 
10 // ...
11}

如果您自訂了複數化器的語言,您應該明確定義您的 Eloquent 模型的資料表名稱

定義翻譯字串

使用短鍵

通常,翻譯字串儲存在 lang 目錄中的檔案中。在這個目錄中,應該為您的應用程式支援的每種語言建立一個子目錄。這是 Laravel 用於管理內建 Laravel 功能(例如驗證錯誤訊息)的翻譯字串的方法

1/lang
2 /en
3 messages.php
4 /es
5 messages.php

所有語言檔案都返回一個鍵控字串陣列。例如

1<?php
2 
3// lang/en/messages.php
4 
5return [
6 'welcome' => 'Welcome to our application!',
7];

對於因地區而異的語言,您應該根據 ISO 15897 命名語言目錄。例如,英國英語應使用 "en_GB" 而不是 "en-gb"。

使用翻譯字串作為鍵

對於具有大量可翻譯字串的應用程式,當在視圖中引用鍵時,使用「短鍵」定義每個字串可能會變得令人困惑,並且為您的應用程式支援的每個翻譯字串不斷發明鍵是很麻煩的。

因此,Laravel 也支援使用字串的「預設」翻譯作為鍵來定義翻譯字串。使用翻譯字串作為鍵的語言檔案以 JSON 檔案形式儲存在 lang 目錄中。例如,如果您的應用程式有西班牙語翻譯,您應該建立一個 lang/es.json 檔案

1{
2 "I love programming.": "Me encanta programar."
3}

鍵 / 檔案衝突

您不應定義與其他翻譯檔案名稱衝突的翻譯字串鍵。例如,為「NL」語系翻譯 __('Action'),同時存在 nl/action.php 檔案,但不存在 nl.json 檔案,將導致翻譯器返回 nl/action.php 的完整內容。

取回翻譯字串

您可以使用 __ 輔助函式從您的語言檔案中取回翻譯字串。如果您使用「短鍵」來定義您的翻譯字串,您應該使用「點」語法將包含鍵的檔案和鍵本身傳遞給 __ 函式。例如,讓我們從 lang/en/messages.php 語言檔案中取回 welcome 翻譯字串

1echo __('messages.welcome');

如果指定的翻譯字串不存在,__ 函式將返回翻譯字串鍵。因此,使用上面的範例,如果翻譯字串不存在,__ 函式將返回 messages.welcome

如果您使用您的預設翻譯字串作為您的翻譯鍵,您應該將您的字串的預設翻譯傳遞給 __ 函式;

1echo __('I love programming.');

同樣地,如果翻譯字串不存在,__ 函式將返回它被給予的翻譯字串鍵。

如果您使用 Blade 模板引擎,您可以使用 {{ }} 輸出語法來顯示翻譯字串

1{{ __('messages.welcome') }}

替換翻譯字串中的參數

如果您願意,您可以在您的翻譯字串中定義佔位符。所有佔位符都以 : 為前綴。例如,您可以定義一個帶有佔位符名稱的歡迎訊息

1'welcome' => 'Welcome, :name',

若要在檢索翻譯字串時替換佔位符,您可以將替換陣列作為第二個參數傳遞給 __ 函式

1echo __('messages.welcome', ['name' => 'dayle']);

如果您的佔位符包含全部大寫字母,或僅首字母大寫,則翻譯後的值將相應地大寫

1'welcome' => 'Welcome, :NAME', // Welcome, DAYLE
2'goodbye' => 'Goodbye, :Name', // Goodbye, Dayle

物件替換格式

如果您嘗試提供物件作為翻譯佔位符,將會調用物件的 __toString 方法。__toString 方法是 PHP 內建的「魔術方法」之一。但是,有時您可能無法控制給定類別的 __toString 方法,例如當您互動的類別屬於第三方函式庫時。

在這些情況下,Laravel 允許您為該特定類型的物件註冊自訂格式處理程序。為了完成此操作,您應該調用翻譯器的 stringable 方法。stringable 方法接受一個閉包,該閉包應該類型提示它負責格式化的物件類型。通常,stringable 方法應該在您的應用程式的 AppServiceProvider 類別的 boot 方法中調用

1use Illuminate\Support\Facades\Lang;
2use Money\Money;
3 
4/**
5 * Bootstrap any application services.
6 */
7public function boot(): void
8{
9 Lang::stringable(function (Money $money) {
10 return $money->formatTo('en_GB');
11 });
12}

複數化

複數化是一個複雜的問題,因為不同的語言對於複數化有各種複雜的規則;但是,Laravel 可以幫助您根據您定義的複數化規則以不同的方式翻譯字串。使用 | 字元,您可以區分字串的單數和複數形式

1'apples' => 'There is one apple|There are many apples',

當然,當使用翻譯字串作為鍵時,也支援複數化

1{
2 "There is one apple|There are many apples": "Hay una manzana|Hay muchas manzanas"
3}

您甚至可以建立更複雜的複數化規則,這些規則指定多個值範圍的翻譯字串

1'apples' => '{0} There are none|[1,19] There are some|[20,*] There are many',

在定義了具有複數化選項的翻譯字串後,您可以使用 trans_choice 函式來檢索給定「計數」的行。在本範例中,由於計數大於 1,因此返回翻譯字串的複數形式

1echo trans_choice('messages.apples', 10);

您也可以在複數化字串中定義佔位符屬性。這些佔位符可以透過將陣列作為第三個參數傳遞給 trans_choice 函式來替換

1'minutes_ago' => '{1} :value minute ago|[2,*] :value minutes ago',
2 
3echo trans_choice('time.minutes_ago', 5, ['value' => 5]);

如果您想顯示傳遞給 trans_choice 函式的整數值,您可以使用內建的 :count 佔位符

1'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。在這個檔案中,您只需要定義您想要覆寫的翻譯字串。任何您沒有覆寫的翻譯字串,仍然會從套件原始的語言檔案中載入。