Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

php - Laravel change locale not working

I am using a dropdown lists for the languages, consisting of english and dutch.

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

Then this is my routes.php,

Route::post('/locale', function(){

     App::setLocale(Request::Input('locale'));

     return redirect()->back();
});

And it is not working.

In my project, the path is like this

resources/
 /du
   navigation.php
 /en
  /navigation.php

From the Dutch(du) 'navigation.php'

<?php
return [
  "home" => 'Home-test-dutch',  
];

and for the English(en) 'navigation.php'

<?php
return [
  "home" => 'Home',  
];
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

App::setLocale() is not persistent, and sets locale only for current request(runtime). You can achieve persistent in multiple ways (example of 2):

Route::post('/locale', function(){

     session(['my_locale' => app('request')->input('locale')]);

     return redirect()->back();
});

This will set session key with lang value from request for current user. Next create a Middleware to set locale based on user session language

<?php namespace AppHttpMiddleware;

use Closure;
use IlluminateHttpRequest;
use IlluminateFoundationApplication;

class Language {

    public function __construct(Application $app, Request $request) {
        $this->app = $app;
        $this->request = $request;
    }

    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $this->app->setLocale(session('my_locale', config('app.locale')));
        
        return $next($request);
    }

}

This will get current session and if is empty will fallback to default locale, which is set in your app config.

In appHttpKernel.php add previously created Language middleware:

protected $middleware = [
   AppHttpMiddlewareLanguage::class,
];

As global middlware or just for web (based on your needs). I hope this helps, and gives an idea on how things are working.

Scenario №2 - Lang based on URL path Create an array with all available locales on your app inside app config

'available_locale' => ['fr', 'gr', 'ja'],

Inside the Middleware we will check the URL first segment en, fr, gr, cy if this segment is in available_locale, set language

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);
}

You will need to modify appProvidersRouteServiceProvider for setting prefix to all your routes. so you can access them domain.com or domain.com/fr/ with French language Find: mapWebRoutes And add this to it: (before add use IlluminateHttpRequest;)

public function map(Request $request)
    {
        $this->mapApiRoutes();
        $this->mapWebRoutes($request);
    }
    protected function mapWebRoutes(Request $request)
    {
        $locale = null;
        if(in_array($request->segment(1), config('app.available_locale'))){
          $locale = $request->segment(1);
        }

        Route::group([
           'middleware' => 'web',
           'namespace' => $this->namespace,
           'prefix' => $locale
        ], function ($router) {
             require base_path('routes/web.php');
        });
    }

This will prefix all your routes with country letter like 'fr gr cy' except en for non-duplicate content, so is better to not add into available_locales_array


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...