web-dev-qa-db-fra.com

Laravel changer les paramètres régionaux ne fonctionne pas

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',  
];
14
Vahn Marty

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"

6
Vahn Marty

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

29
Froxz

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:

  • Aucun bogue possible en raison de l'utilisation de la session (changement de langue "magique")
  • Vous pouvez réécrire vos itinéraires. Un utilisateur français voudra peut-être voir "/ mon-panier" et l'utilisateur anglais "/ my-cart" dans leur URL.
  • Meilleure indexation dans google (SEO), car vous pouvez avoir un véritable index par pays avec un contenu pertinent.
  • Je l'utilise en production!

Il peut aussi avoir ses inconvénients.

3
rap-2-h

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 :)

0
martindilling