我正在使用语言的下拉列表,包括英语和荷兰语。
<form class="" action="{{url('/locale')}}" method="post">
Locale:
<select class="" name="locale" onchange="this.form.submit()">
<option value="en" >English</option>
<option value="du" >Dutch</option>
</select>
</form>
然后这是我的routes.php,
Route::post('/locale', function(){
\App::setLocale(Request::Input('locale'));
return redirect()->back();
});
它不起作用。
在我的项目中,路径就像这样
resources/
/du
navigation.php
/en
/navigation.php
来自荷兰语(du)'navigation.php'
<?php
return [
"home" => 'Home-test-dutch',
];
和英语(en)'navigation.php'
<?php
return [
"home" => 'Home',
];
答案 0 :(得分:27)
App::setLocale()
不是持久的,它仅为当前请求(运行时)设置区域设置。你能做什么:
Route::post('/locale', function(){
session(['my_locale' => Request::Input('locale')]);
return redirect()->back();
});
这会为当前用户设置 session key
我们需要 Middleware
来检测区域设置
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Foundation\Application;
class Language {
public function __construct(Application $app, Request $request) {
$this->app = $app;
$this->request = $request;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$this->app->setLocale(session('my_locale', config('app.locale')));
return $next($request);
}
}
这将获得当前会话,如果为空,则将回退到默认语言环境,该语言环境在应用程序配置中设置。
在app\Http\Kernel.php
中添加以前创建的Language
中间件:
protected $middleware = [
\App\Http\Middleware\Language::class,
];
作为全球middlware或仅为web(根据您的需要)。 我希望这会有所帮助,并对事情的运作方式提出一些看法。
情景№2
在array
app config
'available_locale' => ['fr', 'gr', 'ja'],
如果此段位于en fr gr cy
,设置语言
available_locale
public function handle($request, Closure $next)
{
if(in_array($request->segment(1), config('app.available_locale'))){
$this->app->setLocale($request->segment(1));
}else{
$this->app->setLocale(config('app.locale'));
}
return $next($request);
}
您需要修改app\Providers\RouteServiceProvider
以便为所有路线设置前缀。因此,您可以使用domain.com
访问domain.com/fr/
或French language
查找:mapWebRoutes
并将其添加到其中:(在添加use Illuminate\Http\Request;
之前)
public function map(Request $request)
{
$this->mapApiRoutes();
$this->mapWebRoutes($request);
}
protected function mapWebRoutes(Request $request)
{
if(in_array($request->segment(1), config('app.available_locale'))){
$locale = $request->segment(1);
}else{
$locale = null;
}
Route::group([
'middleware' => 'web',
'namespace' => $this->namespace,
'prefix' => $locale
], function ($router) {
require base_path('routes/web.php');
});
}
这将为您的所有路线添加国家/地区字母前缀,例如'fr gr cy',但非重复内容除外,因此最好不要添加到available_locales_array
答案 1 :(得分:5)
我在本文https://mydnic.be/post/laravel-5-and-his-fcking-non-persistent-app-setlocale
中解决了我的问题感谢那些贡献“非持久性”一词的人
答案 2 :(得分:2)
App::setLocale()
不持久。
我之前遇到过类似的问题所以我创建了一个中间件:
<?php
namespace App\Http\Middleware;
use Closure;
class SetLocale
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (strpos($request->getHttpHost(), 'fr.') === 0) {
\App::setLocale('fr');
} else {
\App::setLocale('en');
}
return $next($request);
}
}
我在app\Http\Kernel
注册了这个中间件:
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\SetLocale::class,
// ...
]
];
此脚本适用于两个域:http://example.org(en)和http://fr.example.org(fr)。作为中间件,它会在每个请求上调用,因此根据URL确定区域设置始终为正确的区域设置。
我的路线看起来像:
Route::group(['domain' => 'fr.' . config('app.root-domain')], function () {
Route::get('a-propos', 'HomeController@about');
// ...
}
Route::group(['domain' => config('app.root-domain')], function () {
Route::get('about', 'HomeController@about');
// ...
}
因此它以正确的语言环境响应:
我使用相同的控制器和相同的视图,只有2条不同的路线+一个全球中间件。
希望它会有所帮助,不确定它是BTW的最佳解决方案。此解决方案在没有sessio的情况下工作,它与域和/或路由匹配。与基于会话的解决方案相比,它具有一些优势:
也可能有它的缺点。
答案 3 :(得分:0)
setLocale
只会在此时更改请求其余部分的语言。
因此,为了坚持下去,您可以考虑在会话中设置所选语言(https://laravel.com/docs/session)。 然后,您可以创建一个middeware(https://laravel.com/docs/middleware),您可以在其中检查会话中是否设置了语言,然后将其应用于请求:)
答案 4 :(得分:0)
当用户从下拉菜单中选择语言时,请拨打以下路线将语言保存到 会议
使用Vue.js
LocalizationComponent.vue 更改语言
<template>
<ul>
<li @click="changeLanguage('en')">
<a href="javascript:void(0);">
<img src="/images/flag-1.png" alt="image description">
<span>ENG</span>
</a>
</li>
<li @click="changeLanguage('vn')">
<a href="javascript:void(0);">
<img src="/images/flag-2.png" alt="image description">
<span>Việt</span>
</a>
</li>
</ul>
<script>
export default{
data(){
return {
selected_language:'en',
}
},
methods:{
changeLanguage(language){
this.axios.post('/change-locale',{language:language}).then(
(response) => {window.location.reload();
}).catch((error) => {
console.log(error.response.data.errors)
});
localStorage.setItem('selected_language',language);
}
}
}
</script>
routes / web.php
Route::post('/change-locale', 'HomeController@changeLocale');
//将语言环境保存到会话中
public function changeLocale(Request $request)
{
$language = $request->language ?? 'en';
session(['selected_language' =>$language]);
}
//创建用于设置语言环境的中间件
class Localization
{
public function handle($request, Closure $next)
{
App::setLocale(session()->get('selected_language') ?? 'en');
return $next($request);
}
}
在app / Http / Kernel.php中
protected $middlewareGroups = [
'web' => [
...other middelwares
Localization::class, //add your localization middleware here
],
//...
];
完成...