Laravel 的簡單 i18n 本地化,這是與 Laravel 本地化類別結合的有用工具。
該套餐提供以下內容:
拉維爾 | laravel 本地化 |
---|---|
4.0.x | 0.13.x |
4.1.x | 0.13.x |
4.2.x | 0.15.x |
5.0.x/5.1.x | 1.0.x |
5.2.x-5.4.x(不需要 PHP 7) | 1.2. |
5.2.0-6.x(需要 PHP 版本 >= 7) | 1.4.x |
6.x-10.x(需要 PHP 版本 >= 7) | 1.8.x |
10.x-11.x(需要 PHP 版本 >= 8.2) | 2.0.x |
透過composer安裝套件: composer require mcamara/laravel-localization
對於 Laravel 5.4 及以下版本,需要註冊服務提供者。
為了編輯預設配置,您可以執行:
php artisan vendor:publish --provider="McamaraLaravelLocalizationLaravelLocalizationServiceProvider"
之後,將建立config/laravellocalization.php
。
配置選項有:
您可以在app/Http/Kernel.php
檔案中註冊套件中間件:
<?php namespace App Http ;
use Illuminate Foundation Http Kernel as HttpKernel ;
class Kernel extends HttpKernel {
/**
* The application's route middleware.
*
* @var array
*/
protected $ middlewareAliases = [
/**** OTHER MIDDLEWARE ****/
' localize ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRoutes::class,
' localizationRedirect ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRedirectFilter::class,
' localeSessionRedirect ' => Mcamara LaravelLocalization Middleware LocaleSessionRedirect::class,
' localeCookieRedirect ' => Mcamara LaravelLocalization Middleware LocaleCookieRedirect::class,
' localeViewPath ' => Mcamara LaravelLocalization Middleware LaravelLocalizationViewPath::class
];
}
如果你使用 Laravel 11,你可以在bootstrap/app.php
檔案中註冊withMiddleware
閉包:
return Application:: configure (basePath: dirname ( __DIR__ ))
// Other application configurations
-> withMiddleware ( function ( Middleware $ middleware ) {
$ middleware -> alias ([
/**** OTHER MIDDLEWARE ALIASES ****/
' localize ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRoutes::class,
' localizationRedirect ' => Mcamara LaravelLocalization Middleware LaravelLocalizationRedirectFilter::class,
' localeSessionRedirect ' => Mcamara LaravelLocalization Middleware LocaleSessionRedirect::class,
' localeCookieRedirect ' => Mcamara LaravelLocalization Middleware LocaleCookieRedirect::class,
' localeViewPath ' => Mcamara LaravelLocalization Middleware LaravelLocalizationViewPath::class,
]);
})
將以下內容新增至您的路由檔案:
// routes/web.php
Route:: group ([ ' prefix ' => LaravelLocalization:: setLocale ()], function ()
{
/** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/
Route:: get ( ' / ' , function ()
{
return View:: make ( ' hello ' );
});
Route:: get ( ' test ' , function (){
return View:: make ( ' test ' );
});
});
/** OTHER PAGES THAT SHOULD NOT BE LOCALIZED **/
一旦將此路由群組新增至路由檔案中,使用者就可以存取新增至supportedLocales
中的所有區域設定(預設為en
和es
)。例如,上面的路由檔案會建立以下位址:
// Set application language to English
http://url-to-laravel/en
http://url-to-laravel/en/test
// Set application language to Spanish
http://url-to-laravel/es
http://url-to-laravel/es/test
// Set application language to English or Spanish (depending on browsers default locales)
// if nothing found set to default locale
http://url-to-laravel
http://url-to-laravel/test
該包根據您的 url 設定您的應用程式區域設定App::getLocale()
。然後,該語言環境可用於 Laravel 的本地化功能。
您可以將中間件新增到您的群組中,如下所示:
Route:: group (
[
' prefix ' => LaravelLocalization:: setLocale (),
' middleware ' => [ ' localeSessionRedirect ' , ' localizationRedirect ' , ' localeViewPath ' ]
], function (){ //...
});
1. :強烈建議使用重定向中間件。不帶區域設定的 URL 只能用於確定瀏覽器/預設區域設定並重定向到本地化 URL。否則,當搜尋引擎機器人抓取例如http://url-to-laravel/test
時,它們可能會為每次訪問獲得不同的語言內容。同樣的內容有多個 url 也會造成 SEO 重複內容問題。
2. :強烈建議本地化您的鏈接,即使您使用重定向中間件。否則,每次用戶單擊連結時,您都會導致至少一次重定向。此外,來自 post 表單的任何操作 URL 都必須本地化,以防止它被重定向到 get 請求。
以下重定向中間件依賴config/laravellocalization.php
中hideDefaultLocaleInURL
和useAcceptLanguageHeader
的設定:
每當 url 中出現語言環境時,該中間件就會將其儲存在會話中。
如果 url 中不存在區域設置,則此中間件將檢查以下內容
useAcceptLanguageHeader
設定為 true,則從瀏覽器計算區域設定並重定向到包含區域設定的 url。hideDefaultLocaleInURL
設定為 true。例如,如果使用者導航到 http://url-to-laravel/test 並且en
是當前語言環境,它會自動將他重定向到 http://url-to-laravel/en/test。
與 LocaleSessionRedirect 類似,但它將值儲存在 cookie 而不是會話中。
每當 url 中出現語言環境時,該中間件就會將其儲存在 cookie 中。
如果 url 中不存在區域設置,則此中間件將檢查以下內容
useAcceptLanguageHeader
設定為 true,則從瀏覽器計算區域設定並重新導向至具有區域設定的 url。hideDefaultLocaleInURL
設定為 true。例如,如果使用者導航到 http://url-to-laravel/test 並且de
是當前語言環境,它會自動將他重定向到 http://url-to-laravel/de/test。
當 url 中存在預設區域設定且hideDefaultLocaleInURL
設定為 true 時,中間件將重定向到不帶區域設定的 url。
例如,如果es
是預設語言環境, http://url-to-laravel/es/test 將被重定向到 http://url-to-laravel/test 並且App::getLocale()
將被設定到es
。
這個包附帶了很多助手。
本地化 URL 在產生本地化路由時考慮了路由模型綁定,以及hideDefaultLocaleInURL
和 Translated Routes 設定。
// If current locale is Spanish, it returns `/es/test`
<a href="{{ LaravelLocalization:: localizeUrl ( ' /test ' ) }}">@ lang ( ' Follow this link ' )</a>
取得特定區域設定中的目前 URL:
// Returns current url with English locale.
{{ LaravelLocalization:: getLocalizedURL ( ' en ' ) }}
傳回沒有任何本地化內容的 URL。
// Returns /about
{{ LaravelLocalization:: getNonLocalizedURL ( ' /es/about ' ) }}
返回一條路由,本地化為所需的區域設定。如果給定的語言環境中不存在翻譯鍵,則函數將傳回 false。
// Returns /es/acerca
{{ LaravelLocalization:: getURLFromRouteNameTranslated ( ' es ' , ' routes.about ' ) }}
使用帶有屬性的路由的本地化鏈路範例
// An array of attributes can be provided.
// Returns /en/archive/ghosts, /fr/archive/fantômes, /pt/arquivo/fantasmas, etc.
<a href="{{ LaravelLocalization:: getURLFromRouteNameTranslated ( App:: currentLocale (), ' routes.archive ' , array ( ' category ' => ' ghosts ' )) }}">Ghost Stories</a>
以數組形式傳回所有受支援的語言環境及其屬性。
{{ LaravelLocalization:: getSupportedLocales () }}
傳回所有支援的區域設置,但按照設定檔中指定的順序。您可以使用此功能在語言選擇器中列印區域設定。
{{ LaravelLocalization:: getLocalesOrder () }}
傳回一個數組,其中包含受支援的語言環境的所有鍵。
{{ LaravelLocalization:: getSupportedLanguagesKeys () }}
傳回目前語言環境的鍵。
{{ LaravelLocalization:: getCurrentLocale () }}
以字串形式傳回目前語言環境的名稱(英語/西班牙語/阿拉伯語/..等)。
{{ LaravelLocalization:: getCurrentLocaleName () }}
以字串形式傳回目前語言環境的本機名稱(英語/西班牙語/法語/..等)。
{{ LaravelLocalization:: getCurrentLocaleNative () }}
以字串形式傳回目前語言環境的區域名稱(en_GB/en_US/fr_FR/ ..etc)。
{{ LaravelLocalization:: getCurrentLocaleRegional () }}
以字串形式傳回目前語言環境的方向 (ltr/rtl)。
{{ LaravelLocalization:: getCurrentLocaleDirection () }}
以字串形式傳回目前語言環境腳本的 ISO 15924 代碼; 「拉丁」、「西爾」、「阿拉伯」等
{{ LaravelLocalization:: getCurrentLocaleScript () }}
註冊中間件LaravelLocalizationViewPath
以將目前語言環境設定為 view-base-path。
現在,您可以將視圖包裝在基於語言的資料夾中,例如翻譯檔案。
resources/views/en/
, resources/views/fr
, ...
由於您甚至可以透過重新命名其鍵來修改supportedLocales,因此可以使用字串uk
而不是en-GB
來提供自訂lang url段。當然,您需要防止與現有金鑰發生任何衝突,並應盡可能長時間地遵守約定。但如果您使用此類自訂鍵,則必須將對應儲存到localesMapping
陣列。需要此localesMapping
來使 LanguageNegotiator 能夠根據 HTTP 接受語言標頭正確分配所需的區域設定。以下是如何將 HTTP 接受語言標頭「en-GB」對應到 url 段「uk」的簡單範例:
// config/laravellocalization.php
' localesMapping ' => [
' en-GB ' => ' uk '
],
之後http://url-to-laravel/uk/a/b/c
http://url-to-laravel/en-GB/a/b/c
uk/a/b/c 。
LaravelLocalization:: getLocalizedURL ( ' en-GB ' , ' a/b/c ' ); // http://url-to-laravel/uk/a/b/c
LaravelLocalization:: getLocalizedURL ( ' uk ' , ' a/b/c ' ); // http://url-to-laravel/uk/a/b/c
如果您在專案中支援多種語言環境,您可能想要為使用者提供更改語言的方法。以下是刀片模板程式碼的簡單範例,您可以使用它來建立自己的語言選擇器。
< ul >
@foreach ( LaravelLocalization :: getSupportedLocales () as $localeCode => $properties )
< li >
< a rel = " alternate " hreflang = " {{ $localeCode } } " href = " {{ LaravelLocalization :: getLocalizedURL ( $localeCode , null , [], true ) } } " >
{{ $properties [ ' native ' ] } }
</ a >
</ li >
@endforeach
</ ul >
這裡,即使hideDefaultLocaleInURL = true
也會強制 getLocalizedURL() 中的預設語言出現在 URL 中。
請注意,支援路由模型綁定。
您可以翻譯您的路線。例如,http://url/en/about 和 http://url/es/acerca(acerca 是西班牙文的 about)或 http://url/en/article/important-article 和 http://url/ es/articulo/important-article(文章是西班牙語的articulo)將被重定向到相同的控制器/視圖,如下所示:
至少必須在Route::group
中間件中載入localize
中間件(請參閱安裝說明)。
對於每種語言,將routes.php
加入到resources/lang/**/routes.php
資料夾中。該檔案包含一個包含所有可翻譯路由的陣列。例如,像這樣:
請記住:從 Laravel 9 開始,
resources/lang
資料夾現在位於根專案資料夾(lang
)中。如果您的專案根目錄中有lang
資料夾,則必須將routes.php
加入到lang/**/routes.php
資料夾中。
<?php
// resources/lang/en/routes.php
return [
" about " => " about " ,
" article " => " article/{article} " ,
];
<?php
// resources/lang/es/routes.php
return [
" about " => " acerca " ,
" article " => " articulo/{article} " ,
];
您可以像這樣在routes/web.php
中加入路由:
Route:: group ([ ' prefix ' => LaravelLocalization:: setLocale (),
' middleware ' => [ ' localize ' ]], function () {
Route:: get (LaravelLocalization:: transRoute ( ' routes.about ' ), function () {
return view ( ' about ' );
});
Route:: get (LaravelLocalization:: transRoute ( ' routes.article ' ), function ( App Article $ article ) {
return $ article ;
});
//,...
});
儲存檔案後,您可以造訪 http://url/en/about 、 http://url/es/acerca 、 http://url/en/article/important-article 和 http://url/es/文章/重要文章沒有任何問題。
也許您在前面的範例中註意到西班牙語 url 中的英語 slug:
http://url/es/articulo/important-article
可以有翻譯後的 slugs,例如這樣:
http://url/en/article/important-change
http://url/es/articulo/cambio-importante
然而,為了做到這一點,每篇文章必須有許多 slugs(每個語言環境一個)。這取決於你想如何實現這種關係。可翻譯路由參數的唯一要求是相關模型實作介面LocalizedUrlRoutable
。
要實作McamaraLaravelLocalizationInterfacesLocalizedUrlRoutable
,必須建立函數getLocalizedRouteKey($locale)
,該函數必須針對給定語言環境傳回翻譯後的 slug。在上面的範例中,在模型文章中, getLocalizedRouteKey('en')
應傳回important-change
, getLocalizedRouteKey('es')
應傳回cambio-importante
。
要使用路由模型綁定,應該覆寫模型中的函數resolveRouteBinding($slug)
。此函數應傳回屬於翻譯後的 slug $slug
的模型。例如:
public function resolveRouteBinding ( $ slug )
{
return static :: findByLocalizedSlug ( $ slug )-> first () ?? abort ( 404 );
}
您可能想觀看此視頻,其中演示瞭如何設定可翻譯的路線參數。
如果您也想翻譯它們,您可以在翻譯過程中擷取 URL 參數。為此,只需為routes.translation
事件建立一個事件偵聽器,如下所示:
Event:: listen ( ' routes.translation ' , function ( $ locale , $ attributes )
{
// Do your magic
return $ attributes ;
});
確保將語言環境和屬性作為參數傳遞給閉包。您也可以使用事件訂閱者,請參閱:http://laravel.com/docs/events#event-subscribers
若要快取您的路線,請使用:
php artisan route:trans:cache
...而不是正常的route:cache
指令。使用artisan route:cache
將無法正常運作!
為了使路由快取解決方案發揮作用,需要對您的應用程式路由配置進行細微調整。
Laravel 11 之前
在應用程式的RouteServiceProvider
中,使用LoadsTranslatedCachedRoutes
特徵:
<?php
class RouteServiceProvider extends ServiceProvider
{
use Mcamara LaravelLocalization Traits LoadsTranslatedCachedRoutes;
Laravel 11 後
在您的應用程式的AppServiceProvider
中,在註冊方法中使用CachedTranslatedRouteLoader
類別:
<?php
class AppServiceProvider extends ServiceProvider
{
use Mcamara LaravelLocalization Traits LoadsTranslatedCachedRoutes;
/**
* Bootstrap any application services.
*/
public function boot(): void
{
RouteServiceProvider:: loadCachedRoutesUsing ( fn () => $ this -> loadCachedRoutes ());
. . .
}
有關更多詳細信息,請參見此處。
如果您沒有本地化Routes::group
內的操作路線,則可能會發生這種情況。這可能會導致重定向,然後將 post 請求變更為 get 請求。為了防止這種情況,只需使用 localize 助手即可。
例如,如果您使用Auth::routes()
並將它們放入您的Route::group
那麼
<form action="/logout" method="POST">
<button>Logout</button>
</form>
不會起作用。相反,人們必須使用
<form action ="{{ LaravelLocalization:: localizeURL ( ' /logout ' ) }} " method= " POST ">
<button>Logout</button>
</form>
解決此問題的另一種方法是將 http 方法配置為“laravellocalization.httpMethodsIgnored”,以防止處理此類請求
如果您沒有本地化您的 post url 並使用重定向中間件,那麼 post 請求將被重定向為 get 請求。如果你沒有定義這樣的get路由,就會導致這個異常。
若要在地化您的貼文網址,請參閱 POST 中的範例不起作用。
如果您沒有本地化您的貼文網址,也會發生這種情況。如果您沒有本地化您的帖子網址,則會在驗證時設置預設區域設置,並且當返回back()
時,它會顯示預設區域設定中的驗證訊息。
若要在地化您的貼文網址,請參閱 POST 中的範例不起作用。
在測試設定期間,所呼叫的路由尚不清楚。這意味著無法設定語言。當在測試期間發出請求時,這會導致 404 - 如果沒有設定前綴,則本地化路由似乎不存在。
若要解決此問題,您可以使用此函數手動設定語言前綴:
// TestCase.php
protected function refreshApplicationWithLocale ( $ locale )
{
self :: tearDown ();
putenv (LaravelLocalization:: ENV_ROUTE_KEY . ' = ' . $ locale );
self :: setUp ();
}
protected function tearDown (): void
{
putenv (LaravelLocalization:: ENV_ROUTE_KEY );
parent :: tearDown ();
}
// YourTest.php
public function testBasicTest ()
{
$ this -> refreshApplicationWithLocale ( ' en ' );
// Testing code
}
如果您想成為其中一員,請詢問 mcamara!
在此查看變更日誌 -> 變更日誌
Laravel Localization 是一個根據 MIT 授權授權的開源 Laravel 套件