如何使用SESSION向Laravel 5.3添加多语言
我想向我的网站添加多语言支持,但我不知道如何最好地实现它。 Laravel文档(https://laravel.com/docs/5.3/localization)非常少见,因此我已经做了一些研究,但似乎每个人都使用不同的解决方案,并且正在使用其中包含语言的URL - 例如example.com/en/pagename
。如何使用SESSION向Laravel 5.3添加多语言
我想要一个没有语言标记的URL架构。事情是这样的:example.com/pagename
现在,根据用户的语言,该URL应译为:
example.com/pagename (english)
example.com/seitenname (german)
最初的语言应该通过浏览器设置/语言检测。用户还应该有选择在提供的语言之间切换。
在我的网站上,用户可以注册一个帐户。他将能够将他的首选语言保存在数据库中 - 比如users
中的表pref_lang
。为了在这种情况下保持简单,它只是一个像“en”(英语)或“德”(德语)的字符串。
翻译的路线很容易通过创建这样的语言文件:
// resources/lang/de/routes.php
return array(
'contact' => 'kontakt',
'pagename' => 'seitenname'
);
...,一个用于EN:
// resources/lang/en/routes.php
return array(
'contact' => 'contact',
'pagename' => 'pagename'
);
......这样的路线,例如combinded:
// routes/web.php
Route::get('/', function() {
return view('pages.dashboard');
});
Route::get('/{contact}', function() {
return view('pages.contact');
});
Route::get('/{pay2gether-system}', function() {
return view('pages.pagename');
});
现在只是一个问题,我如何创建这样一个“语言切换”按钮,将语言从浏览器设置/切换操作或从SESSION中的数据库中获取数据,以及如何将其重用为HTML <a href="#">
标记中的路由和URL?
我这样做了几次,这很容易完成。按照下面的步骤,如果您有任何其他问题,请随时询问。
- 在
users
表中创建一个language
列。这是我过去设置的方式,$table->string('language')->default('en');
- 创建一个新的中间件来检测语言更改,例如:
SetLanguage
。 - 将中间件添加到
app\Http\Kernel.php
中的web
中间件组的底部。 -
将以下内容粘贴到
handle
方法中。if ($request->has('language')) { if (auth()->user()) { auth()->user()->language = $request->language; auth()->user()->save(); } App::setLocale($request->language); } elseif (auth()->user()) { App::setLocale(auth()->user()->language); } return $next($request);
-
创建一个服务提供商,并在您
config/app.php
注册,并在引导方法粘贴下面的代码。view()->composer('template.name', function($view) { $languages = []; $folders = File::directories(base_path('resources/lang/')); foreach ($folders as $folder) { $languages[] = str_replace('\\', '', last(explode('/',$folder))); } $view->with('languages', $languages); });
现在您的
template.name.blade.php
你可以通过在你的应用程序中可用的语言循环。
在您的下拉菜单中,您应该使用{{ url('/') . '?language=' . $language }}
作为循环时的链接。您可以将language
键更改为其他名称,但如果这样做了,则还必须在中间件中更改它。
我会做一些在中间件:
public function handle($request, Closure $next)
{
if ($request->has('language')) {
$path = $request->path();
$locale = $request->get('language');
# save locale
Cookie::queue(Cookie::make(
'language', $locale, 1440 // 24h
));
# set locale
\App::setLocale($locale);
return redirect($path)->withCookie(cookie('language'));
}
if ($locale = $request->cookie('language')) {
\App::setLocale($locale);
}
return $next($request);
}
现在的供应商:
public function boot()
{
View::composer('template.name', function($view) {
$directory = base_path('resources/lang/');
$languages = \File::directories($directory);
$view->with('languages', array_map('basename', $languages));
});
}
并在视图:
<ul class="dropdown-menu" role="menu">
@foreach ($languages as $lang)
<li>
<a href="{{ url()->current() . '/?language=' . $lang }}" title="">{{ $lang }}</a>
</li>
@endforeach
</ul>
我不能,如果十分确定这是一个最好的解决方案...也许有更多Laravel经验的人可以向我们展示另一种解决方案
尽管如此,代码优化并不是问题的关键。你是指另一个答案?这还不够清楚。 –
谢谢,但Laravel从浏览器中读取第一个/默认语言,如果它尚未设置在数据库中,它在哪里?这是缺少,或?另外:我不想像'{{url('/')那样存储语言。 '?language ='。 $ language}}',但在cookie/session中。这不可能吗? – user2966991
数据库中有一个默认值,它被设置为'en'。你可以改变它到任何你想要的。 – tomirons