1
votes

My app can change locale using url request.

Route::get('/setLocale/{locale}', function (Request $request, $locale) {
    session()->put('locale', $locale);
    App::setLocale($locale);
    return redirect('/');
})->name('setLocale');

And that locale string would be stored in session. I use middleware to dynamically change locale using the session data if there's any.

public function handle($request, Closure $next)
    {
        if (session('locale')) {
            App::setLocale(session('locale'));
        }
        return $next($request);
    }

The problem is that App::getLocale() in web.php always return default locale settings, even when the locale is set to the other one (because I can see different text on web).

$locale = App::getLocale();

dd($locale); // default locale set in config.php

I tried using session('locale'), but it always return null. I am pretty sure it's set in session because I can see the website has that locale.

The reason I need reference of locale is because I want to generate dynamic route prefix based on locale.

$locale = App::getLocale();

Route::prefix($locale)->group(function () {
   ....
});

I am wondering what's the problem here? Is it because session isn't instantiated before routes?


Kernal.php

protected $middlewareGroups = [
        'web' => [
            ... (default)
            \App\Http\Middleware\SetLocale::class,
        ],
    ];

So I dd() the App::getLocale() on web.php and on my globle web middleware, dd() on web.php gets printed first...

So I get web.php is called before any global middlewares are registerd. But then how can I set dynamic prefix based on locale???

2
@Wreigh, the problem is not setting the locale in the middleware, because it works in my case. The problem is that I can't get session('locale') or the correct value of App::getLocale() in web.php...Joshua Leung
have you read it? the question there seems to have the same nature as with your problem.Wreigh
did you see this already mydnic.be/post/…? where do you call App::getLocale()? is that inside a route group with the above middleware?Wreigh
@Wreigh App::getLocale(); is not in any route function, it's at the "outermost" scope of the web.php. Not in any function... Because I need define this variable in the global scope, only then I can set dynamic prefix.Joshua Leung

2 Answers

4
votes

You can use something like this

here is the routes

Route::group(['middleware' => ['language']], function () {
   Route::get('/language/{locale}', [
    'uses' => 'Frontend\LanguageController@changeLanguage',
    'as' => 'language.changer',
    'role' => ['company', 'user']
   ]);
});

here is the language controller

<?php

 namespace App\Http\Controllers\Frontend;
 use Illuminate\Http\Request;
 use App\Http\Controllers\Controller; 
 use Session;

class LanguageController extends Controller
{
public function changeLanguage($locale){
    Session::put('locale', $locale);
    return redirect()->back();
}
}

this is the middleware

public function handle($request, Closure $next)
{
    if (Session::has('locale') == true) {

        App::setLocale(Session::get('locale'));
    }
    Carbon::setLocale(Session::get('locale'));
    return $next($request);
}

and this to set up your default locale if something went wrong

public function boot()
{
    Schema::defaultStringLength(191);
    if(Session::has('locale') == false)
    {
        App::setLocale('en');
    }
}

finally you can use something like that :

<li class="is-relative hidden-lg hidden-md">
   <a href="/logout">
      <i class="fa fa-power-off"></i> 
      {{ trans('lang.logout') }}
     <span class="sr-only">(current)</span>
  </a>
</li>

hope this helps you ..

1
votes

You can set and get the locale application using this global helper in your web.php file:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
app()->setLocale('en');
dd(app()->getLocale());

But your middleware will be applied after you request access some route not before. So, to test your app locale put this code dd(app()->getLocale()) inside your controller.

This should work.