mcamara / laravel-localization
Laravel的本地化工具,易于使用
Requires
- php: >=7.1.0
- laravel/framework: ~5.2.0||~5.3.0||~5.4.0||~5.5.0||~5.6.0||~5.7.0||~5.8.0||^6.0||^7.0||^8.0||^9.0|^10.0||^11.0
Requires (Dev)
- orchestra/testbench-browser-kit: ~3.4|~3.8|~4.0|^7.12|^8.5
- phpunit/phpunit: 6.0.*|^8.0|^9.5.10|^10.0
Suggests
- ext-intl: *
- dev-master
- v2.0.1
- V1.8.0
- v1.7.0
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.8
- 1.4.7
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.20
- 1.3.19
- 1.3.18
- 1.3.17
- 1.3.16
- 1.3.15
- 1.3.14
- 1.3.13
- 1.3.12
- 1.3.11
- 1.3.10
- 1.3.9
- v1.3.8
- 1.3.7
- v1.3.6
- v1.3.5
- v1.3.4
- 1.3.3
- 1.3.2
- 1.3.1
- 1.3.0
- v1.2.7
- v1.2.6
- v1.2.5
- v1.2.4
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.x-dev
- 1.1.12
- 1.1.11
- 1.1.10
- 1.1.9
- 1.1.8
- 1.1.7
- 1.1.6
- 1.1.5
- 1.1.4
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.x-dev
- 1.0.13
- 1.0.12
- 1.0.11
- 1.0.10
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.0
- 0.15.x-dev
- 0.15.2
- 0.15.1
- 0.15.0
- 0.14.9
- 0.14.8
- 0.14.7
- 0.14.6
- 0.14.4
- 0.14.3
- 0.14.2
- 0.14.1
- 0.14.0
- 0.13.8
- 0.13.7
- 0.13.6
- 0.13.5
- 0.13.3
- 0.13.2
- 0.13.1
- 0.13.0
- 0.12.0
- 0.11.0
- 0.10
- 0.9
- 0.8
- dev-fix_tests
- dev-revert-526-patch-2
- dev-development
This package is auto-updated.
Last update: 2024-08-24 09:42:31 UTC
README
为Laravel提供易于使用的i18n本地化工具,是一个与Laravel本地化类结合使用的实用工具。
该包提供以下功能:
- 从浏览器中检测语言
- 智能重定向(在会话/cookie中保存区域设置)
- 智能路由(只需定义一次路由,无论使用多少种语言)
- 可翻译的路由
- 支持缓存和测试
- 隐藏默认区域设置的选项
- 许多片段和助手(如语言选择器)
目录
Laravel兼容性
安装
使用composer安装包: composer require mcamara/laravel-localization
对于Laravel 5.4及以下版本,需要注册服务提供者。
配置文件
为了编辑默认配置,您可以执行以下操作:
php artisan vendor:publish --provider="Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider"
之后,将创建 config/laravellocalization.php
文件。
配置选项如下:
- supportedLocales 应用程序的语言(默认:英语和西班牙语)。
- useAcceptLanguageHeader 如果为真,则自动从浏览器中检测语言。
- hideDefaultLocaleInURL 如果为真,则不在URL中显示默认区域设置。
- localesOrder 按自定义顺序排序语言。
- localesMapping 重命名URL区域设置。
- utf8suffix 允许更改CentOS等的utf8suffix。
- urlsIgnored 忽略特定URL。
注册中间件
您可以在 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.:强烈建议您本地化链接,即使您使用重定向中间件也是如此。否则,每次用户点击链接时,都会至少进行一次重定向。此外,任何来自表单的动作URL都必须进行本地化,以防止它被重定向到GET请求。
重定向中间件
以下重定向中间件依赖于配置文件 config/laravellocalization.php
中的 hideDefaultLocaleInURL
和 useAcceptLanguageHeader
设置。
LocaleSessionRedirect
每当URL中存在区域设置时,该中间件就会将其存储在会话中。
如果URL中没有区域设置,则此中间件将检查以下内容:
- 如果没有在会话中保存区域设置,并且将
useAcceptLanguageHeader
设置为true,则从浏览器计算区域设置并将用户重定向到包含区域设置的URL。 - 如果会话中保存了区域设置,则将用户重定向到包含区域设置的URL,除非它是默认区域设置且将
hideDefaultLocaleInURL
设置为true。
例如,如果用户导航到 http://url-to-laravel/test,并且当前区域设置为 en
,则它将自动将其重定向到 http://url-to-laravel/en/test。
LocaleCookieRedirect
类似于LocaleSessionRedirect,但它将值存储在cookie中而不是会话中。
每当URL中存在区域设置时,该中间件就会将其存储在cookie中。
如果URL中没有区域设置,则此中间件将检查以下内容:
- 如果没有在cookie中保存区域设置,并且将
useAcceptLanguageHeader
设置为true,则从浏览器计算区域设置并将用户重定向到包含区域设置的URL。 - 如果在cookie中保存了区域设置,则将用户重定向到包含区域设置的URL,除非它是默认区域设置且将
hideDefaultLocaleInURL
设置为true。
例如,如果用户导航到 http://url-to-laravel/test,并且当前区域设置为 de
,则它将自动将其重定向到 http://url-to-laravel/de/test。
LaravelLocalizationRedirectFilter
当默认区域设置存在于URL中且将 hideDefaultLocaleInURL
设置为true时,中间件将重定向到不包含区域设置的URL。
例如,如果默认区域设置为 es
,则 http://url-to-laravel/es/test 将被重定向到 http://url-to-laravel/test,并且 App::getLocale()
将被设置为 es
。
助手
此包附带了一些辅助函数。
本地化URL
在生成本地化路由时,本地化URL会考虑路由模型绑定,以及 hideDefaultLocaleInURL
和 Translated Routes 设置。
获取本地化URL
// If current locale is Spanish, it returns `/es/test` <a href="{{ LaravelLocalization::localizeUrl('/test') }}">@lang('Follow this link')</a>
获取特定区域设置的本地化URL
获取特定区域设置中的当前URL
// Returns current url with English locale. {{ LaravelLocalization::getLocalizedURL('en') }}
获取干净的路线
返回不包含任何本地化的URL。
// Returns /about {{ LaravelLocalization::getNonLocalizedURL('/es/about') }}
获取特定翻译键的URL
返回指向所需区域设置的路线,本地化到该区域设置。如果给定的区域设置中不存在翻译键,则此函数将返回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() }}
获取当前区域的本地名称
以字符串形式返回当前区域的本地名称(英语/Español/عربى/等等)。
{{ LaravelLocalization::getCurrentLocaleNative() }}
获取当前区域的区域名称
以字符串形式返回当前区域的区域名称(en_GB/en_US/fr_FR/等等)。
{{ LaravelLocalization::getCurrentLocaleRegional() }}
获取当前区域的书写方向
以字符串形式返回当前区域的书写方向(ltr/rtl)。
{{ LaravelLocalization::getCurrentLocaleDirection() }}
获取当前区域的脚本
以字符串形式返回当前区域脚本的国际标准化组织15924代码;例如 "Latn", "Cyrl", "Arab" 等。
{{ LaravelLocalization::getCurrentLocaleScript() }}
将视图基本路径设置为当前区域
注册中间件 LaravelLocalizationViewPath
以设置当前区域为视图基本路径。
现在您可以在基于语言的文件夹中包装您的视图,就像翻译文件一样。
resources/views/en/
,resources/views/fr
,...
映射您自己的自定义语言URL段
由于您可以通过重命名键来修改支持的区域,因此可以使用字符串 uk
而不是 en-GB
来提供自定义语言URL段。当然,您需要防止与已存在的键发生冲突,并且应尽可能遵守约定。但是,如果您使用此类自定义键,则必须将映射存储在 localesMapping
数组中。此 localesMapping
是使语言协商者能够根据HTTP接受语言头正确分配所需区域所必需的。以下是一个快速示例,如何将HTTP接受语言头 'en-GB' 映射到URL段 'uk'
// config/laravellocalization.php 'localesMapping' => [ 'en-GB' => 'uk' ],
之后,http://url-to-laravel/en-GB/a/b/c
就变成了 http://url-to-laravel/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
创建语言选择器
如果您在项目中支持多个区域,您可能希望为用户提供更改语言的方式。以下是您可以使用以创建自己的语言选择器的简单 blade 模板代码的示例。
<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 是西班牙语中的“关于”)或 http://url/en/article/important-article 和 http://url/es/articulo/important-article(article 是西班牙语中的 articulo)将重定向到以下相同的控制器/视图
有必要在您的 Route::group
中间件中加载至少 localize
中间件(参见 安装说明)。
对于每种语言,在 resources/lang/**/routes.php
文件夹中添加一个 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/articulo/important-article。
可翻译的路由参数
也许您已经注意到了上一个示例中的西班牙语URL中的英文slug
http://url/es/articulo/important-article
可以有翻译后的slug,例如像这样
http://url/en/article/important-change
http://url/es/articulo/cambio-importante
然而,为了做到这一点,每篇文章必须有许多slug(每个地区一个)。这取决于您如何实现这种关系。对于可翻译的路由参数的唯一要求是,相关的模型实现了LocalizedUrlRoutable
接口。
实现LocalizedUrlRoutable
要实现\Mcamara\LaravelLocalization\Interfaces\LocalizedUrlRoutable
,需要创建一个函数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参数,可以捕获URL参数。为此,只需为routes.translation
事件创建一个事件监听器,如下所示
Event::listen('routes.translation', function($locale, $attributes) { // Do your magic return $attributes; });
请确保将地区和属性作为参数传递给闭包。您还可以使用事件订阅者,请参阅:https://laravel.net.cn/docs/events#event-subscribers
缓存路由
要缓存您的路由,请使用
php artisan route:trans:cache
...而不是正常的route:cache
命令。使用artisan route:cache
将无法正确工作!
为了使路由缓存解决方案正常工作,需要对应用程序的路由配置进行一些小的调整。
在laravel 11之前
在您的App的RouteServiceProvider
中,使用LoadsTranslatedCachedRoutes
特征
<?php class RouteServiceProvider extends ServiceProvider { use \Mcamara\LaravelLocalization\Traits\LoadsTranslatedCachedRoutes;
在laravel 11之后
在您的App的AppServiceProvider
中,在register方法中使用CachedTranslatedRouteLoader
类
<?php class AppServiceProvider extends ServiceProvider { use \Mcamara\LaravelLocalization\Traits\LoadsTranslatedCachedRoutes; /** * Bootstrap any application services. */ public function boot(): void { RouteServiceProvider::loadCachedRoutesUsing(fn() => $this->loadCachedRoutes()); ... }
有关更多详细信息,请参阅此处。
常见问题
POST请求不工作
如果您没有对位于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'以防止处理此类型请求
MethodNotAllowedHttpException
如果您没有对POST URL进行本地化并使用重定向中间件,那么POST请求将被重定向为GET请求。如果您没有定义此类GET路由,您将引发此异常。
要本地化您的POST URL,请参阅POST不起作用中的示例。
验证消息仅位于默认地区
这也可能发生在您没有对POST URL进行本地化的情况下。如果您没有对POST URL进行本地化,则在验证时设置默认地区,当返回到back()
时,它将显示默认地区的验证消息。
要本地化您的POST URL,请参阅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 是一个开源的 Laravel 包,采用 MIT 许可证授权