044. Laravel 本地化功能增强,切换项目语言——mcamara/laravel-localization
Laravel 本地化功能增强,切换项目语言——mcamara/laravel-localization
对于一个多国语言的项目,切换语言是一个很重要的功能,看一眼我们熟悉的 php.net :
首先能根据浏览器来确定语言,能根据不同的 URL 参数确定不同的语言,用户也需要方便的切换。今天要学习的扩展包 mcamara/laravel-localizatio 就可以很好的满足这些需求。
安装
上节课 翻译辅助工具——barryvdh/laravel-translation... 中介绍了辅助翻译的工具,并在首页中添加了一个翻译。这节课我们继续在这个分支上,看看扩展包如何帮我们切换语言。
$ composer require mcamara/laravel-localization
发布配置文件
$ php artisan vendor:publish --provider="Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider"
使用
首先需要修改一下配置,配置文件中的 supportedLocales 制定了项目支持的语言。
config/laravellocalization.php
'supportedLocales' => [
'en' => ['name' => 'English', 'script' => 'Latn', 'native' => 'English', 'regional' => 'en_GB'],
'zh-CN' => ['name' => 'Chinese (Simplified)', 'script' => 'Hans', 'native' => '简体中文', 'regional' => 'zh_CN'],
]
设置 en
和 zh-CN
,也就是支持 英文
以及 简体中文
。其他有两个重要的配置需要解释一下:
laravellocalization.useAcceptLanguageHeader
—— 如果没有传递语言参数,使用 HTTP Accept-Language 头来设置语言,如果 Accept-Language 错误则使用项目默认的语言,也就是 app.locale
;laravellocalization.hideDefaultLocaleInURL
—— 隐藏默认语言参数,如果没有传递语言参数,直接使用项目默认的语言 app.locale
;
我们将 useAcceptLanguageHeader
设置为 true,将 hideDefaultLocaleInURL
设置为 false,这样可以根据浏览器语言来决定默认语言,如果不支持浏览器语言,则会使用项目设置的默认语言。
增加 Prefix
然后修改一下路由,增加一个 prefix
——LaravelLocalization::setLocale
。
routes/web.php
Route::group(['prefix' => LaravelLocalization::setLocale()], function() {
route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
});
这样基本就配置完成了,访问一下首页 package.test 。
由于当前浏览器使用的语言是中文,所以默认设置语言为 zh-CN,访问 package.test/zh-CN 和 package.test/en 扩展包会根据参数进行语言设置,可以看到语言的变化。
如果设置浏览器默认的语言为英文,那么再次访问首页:
如果现在将
hideDefaultLocaleInURL
设置为 true,则不会根据 Accept-Language 也就是浏览器语言决定默认语言。
其他中间件
此外扩展包还提供了几个中间件,注册一下中间件:
app/Http/Kernel.php
.
.
.
protected $routeMiddleware = [
.
.
.
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class
];
.
.
.
LaravelLocalizationRoutes
中间件是用于多语言 URL 的转换,例如英文 URL 显示 view/{id}
,西班牙语显示 ver/{id}
,一般情况下对于中英文切换的项目用不到,我们主要看剩下三个中间件。
routes/web.php
.
.
.
Route::group([
'prefix' => LaravelLocalization::setLocale(),
'middleware' => ['localeSessionRedirect', 'localizationRedirect', 'localeViewPath']
], function() {
.
.
.
LaravelLocalizationRedirectFilter 和 LocaleSessionRedirect 两个中间件是用于将 URL 跳转到带语言参数的 URL 中,也就是例如将 http://package.test/login
跳转到 http://package.test/en/login
。但是这两个中间件的处理逻辑会根据 hideDefaultLocaleInURL 这个配置有些不同:
现在我们的 hideDefaultLocaleInURL
为 false
,URL 会根据浏览器语言强制添加语言参数:
- 如果浏览器是英文, package.test/ 会跳转到 package.test/en ;
- 如果浏览器是中文, package.test/login 会跳转到 package.test/zh-CN/login 。
如果设置 hideDefaultLocaleInURL
为 true
,则当浏览器使用的语言与项目语言(app.locale)一致时,强制隐藏语言参数,现在项目的默认语言是简体中文(zh-CN):
- 如果浏览器是英文, package.test/ 会跳转到 package.test/en ,语言设置为中文;
- 如果浏览器是中文, package.test/login 则不会跳转,语言设置为中文 ;
- 无论浏览器是什么语言, package.test/zh-CN/login 都会跳转到 package.test/login ,并将语言设置为中文。
当前语言都会保存在 Session 中,用户下次再次访问会根据上次的使用情况进行跳转。
另一个中间件 LaravelLocalizationViewPath 允许我们根据不同的语言,使用不同的 view,先创建一个路由:
routes/web.php
.
.
.
Route::get('localization', function() {
return view('localization');
});
.
.
.
默认情况下会使用 resources/views/localization.blade.php
这个视图,但是可以根据不同的语言进行设置,在resources/views
目录下根据语言创建两个文件夹以及文件:
$ mkdir en
$ mkdir zh-CN
$ touch resources/views/en/localization.blade.php
$ touch resources/views/zh-CN/localization.blade.php
填入不同语言的内容。
视图切换语言
最后我们可以在 header 中增加一个下拉菜单,进行语言的切换,代码可以非常简单:
layouts/app.blade.php
<!-- Right Side Of Navbar -->
<ul class="nav navbar-nav navbar-right">
.
.
.
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" v-pre>
{{ LaravelLocalization::getCurrentLocaleName() }} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
@foreach(LaravelLocalization::getSupportedLocales() as $localeCode => $properties)
<li>
<a rel="alternate" hreflang="{{ $localeCode }}" href="{{ LaravelLocalization::getLocalizedURL($localeCode, null, [], true) }}">
{{ $properties['native'] }}
</a>
</li>
@endforeach
</ul>
</li>
</ul>
.
.
.
可以在项目 Header 中设置一个类似的下拉菜单,展示所有支持的语言,让用户切换。
代码版本控制
$ git add -A
$ git commit -m 'mcamara/laravel-localization'