Laravel 5 And His F*cking non-persistent App SetLocale
Hey! Looking for a more SEO Friendly way to manage a multilingual application with Laravel5 ? Check this tutorial!
Edit: This article have been updated to match Laravel 5.2 architecture.
If you ever have worked already with Laravel 5 (if not, you should), and that you needed a decent way to switch language into your application, well good luck.
The thing is, it was really easier with Laravel 4.
Ok I'm not going to explain why and how and all, because you know that I mainly use my website to store snippets and reminder about HOW I SOLVED THIS NIGHTMARE OF A PROBLEM.
Relax.
In most of my applications, I don't really like having the language in the URI, because it messes with my Route file, and I have to update all my links.. Anyway, here's how I managed to build a simple Language Switcher, that will just update the localization of your application, and refresh the page.
First, create a new controller "LanguageController". You can use this command : php artisan make:controller LanguageController
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use Config;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Session;
class LanguageController extends Controller
{
public function switchLang($lang)
{
if (array_key_exists($lang, Config::get('languages'))) {
Session::put('applocale', $lang);
}
return Redirect::back();
}
}
Ok, as you see we use a custom config array to fetch the available languages of the app, so lets create a **languages.php **in the config/ directory :
return [
'en' => 'English',
'fr' => 'Français',
];
Good! Now to use our controller, we are going to set up one new route:
Route::get('lang/{lang}', ['as' => 'lang.switch', 'uses' => 'LanguageController@switchLang']);
Be careful, if you use Laravel 5.2, you need to put all your routes, including this new one, into a route group that implements the "web" middleware group (as we will put the middleware in this group)
You should now be able to use a Language dropdown (I often put it in my navbar). Check this example based on boostrap dropdown :
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{ Config::get('languages')[App::getLocale()] }}
</a>
<ul class="dropdown-menu">
@foreach (Config::get('languages') as $lang => $language)
@if ($lang != App::getLocale())
<li>
<a href="{{ route('lang.switch', $lang) }}">{{$language}}</a>
</li>
@endif
@endforeach
</ul>
</li>
Last thing to do is to set up a new Middleware:
// app/Http/Middleware/Language.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Session;
class Language
{
public function handle($request, Closure $next)
{
if (Session::has('applocale') AND array_key_exists(Session::get('applocale'), Config::get('languages'))) {
App::setLocale(Session::get('applocale'));
}
else { // This is optional as Laravel will automatically set the fallback language if there is none specified
App::setLocale(Config::get('app.fallback_locale'));
}
return $next($request);
}
}
And of course we do not forget to update Kernel.php with our new Middleware (check the order I use)
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\Language::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
// ...
];
That's it !! Enjoy :)
I consider myself as an IT Business Artisan. Or Consultant CTO. I'm a self-taught Web Developper, coach and teacher. My main work is helping and guiding digital startups.
more about meBTC
18SY81ejLGFuJ9KMWQu5zPrDGuR5rDiauM
ETH
0x519e0eaa9bc83018bb306880548b79fc0794cd08
XMR
895bSneY4eoZjsr2hN2CAALkUrMExHEV5Pbg8TJb6ejnMLN7js1gLAXQySqbSbfzjWHQpQhQpvFtojbkdZQZmM9qCFz7BXU
2024 © My Dynamic Production SRL All rights Reserved.