J'utilise une liste déroulante pour les langues, comprenant l'anglais et le néerlandais.
<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>
Alors voici mes routes.php,
Route::post('/locale', function(){
\App::setLocale(Request::Input('locale'));
return redirect()->back();
});
Et ça ne marche pas.
Dans mon projet, le chemin est comme ça
resources/
/du
navigation.php
/en
/navigation.php
Du néerlandais (du) 'navigation.php'
<?php
return [
"home" => 'Home-test-dutch',
];
et pour l'anglais (fr) 'navigation.php'
<?php
return [
"home" => 'Home',
];
J'ai résolu mon problème à partir de cet article https://mydnic.be/post/laravel-5-and-his-fcking-non-persistent-app-setlocale
Merci aux personnes qui ont contribué à la Parole "non persistante"
App::setLocale()
n'est pas persistant, il ne définit les paramètres régionaux que pour la requête actuelle (runtime). Ce que tu peux faire:
Route::post('/locale', function(){
session(['my_locale' => Request::Input('locale')]);
return redirect()->back();
});
Cela définira session key
pour l'utilisateur actuel Après nous aurons besoin d'un Middleware
pour détecter les paramètres régionaux
<?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);
}
}
Cela obtiendra la session en cours et s'il est vide, il reviendra aux paramètres régionaux par défaut, qui sont définis dans la configuration de votre application.
Dans app\Http\Kernel.php
ajouter le middleware Language
créé précédemment:
protected $middleware = [
\App\Http\Middleware\Language::class,
];
En tant que logiciel intermédiaire mondial ou uniquement pour le Web (en fonction de vos besoins). J'espère que cela aide et donne une idée de la façon dont les choses fonctionnent.
Scénario №2 Créez un array
avec tous les paramètres régionaux disponibles sur votre application à l'intérieur app config
'available_locale' => ['fr', 'gr', 'ja'],
À l'intérieur du middleware, nous vérifierons le premier segment de l'URL en fr gr cy
si ce segment est en available_locale
, Définir la langue
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);
}
Vous devrez modifier app\Providers\RouteServiceProvider
pour définir le préfixe de tous vos itinéraires. afin que vous puissiez y accéder domain.com
ou domain.com/fr/
avec French language
Trouver: mapWebRoutes
Et ajouter ceci: (avant d'ajouter 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');
});
}
Cela préfixera tous vos itinéraires avec une lettre de pays comme "fr gr cy" sauf en pour le contenu non dupliqué, il est donc préférable de ne pas ajouter dans available_locales_array
App::setLocale()
n'est pas persistant. J'ai eu un problème similaire auparavant, alors j'ai créé un middleware:
<?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);
}
}
Et j'ai enregistré ce middleware dans app\Http\Kernel
:
protected $middlewareGroups = [
'web' => [
// ...
\App\Http\Middleware\SetLocale::class,
// ...
]
];
Ce script fonctionne pour deux domaines: http://example.org (en) et http://fr.example.org (fr). En tant que middleware, il est appelé à chaque demande, donc les paramètres régionaux sont toujours définis comme les bons paramètres régionaux en fonction de l'URL.
Mes itinéraires ressemblaient à:
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');
// ...
}
Il répond donc avec les paramètres régionaux corrects à:
Et j'utilise le même contrôleur et la même vue, juste 2 routes différentes + un middleware global.
J'espère que cela vous aidera, pas sûr que ce soit la meilleure solution BTW. Cette solution fonctionne sans sessio, elle correspond au domaine et/ou aux routes. Il présente certains avantages par rapport aux solutions basées sur les sessions:
Il peut aussi avoir ses inconvénients.
setLocale
ne changera la langue que pour le reste de la demande à partir de ce moment.
Donc, pour le conserver, vous pouvez envisager de définir la langue sélectionnée dans une session ( https://laravel.com/docs/session ). Ensuite, vous pouvez créer un middeware ( https://laravel.com/docs/middleware ) où vous pouvez vérifier si une langue est définie dans la session, puis l'appliquer pour la demande :)