I'm trying to implement easy multi-language routing based on locale in Laravel 5.6.28, but have stuck with redirect after language change.
I would like to immediately redirect users to proper route based on changed locale whenever they changing it from form select on page.
I also made two middleware classes:
1. SetLocale - For set locale if not set using HTTP_ACCEPT_LANGUAGE or considering first segment of reqeust (locale exactly).
2. LocaleRedirect - For compare user and request locales and redirect if they didn't match.
For example, if route was '/en/blog/stackoverflow'
After changing locale it should be '/gr/blog/stackoverflow'
But redirect does not occur. What I did wrong?
Many thanks.
Locales:
'locales' => [
'en' => 'English',
'es' => 'Spanish',
'gr' => 'Greek'
]
Page:
{!! Form::open(['route' => 'language.change']) !!}
Language:
{!! Form::select('lang', config('translatable.locales'), app()->getLocale(), ['id' => 'language-select']); !!}
{!! Form::close() !!}
<script>
$(function () {
$('#language-select').on('change', function () {
$(this).closest('form').submit();
});
});
</script>
Routes:
Route::post('language/change', 'LanguageController@postChangeLanguage')->name('language.change');
Route::group([
'prefix' => '{locale}',
'middleware' => ['setlocale', 'locale-redirect'],
'where' => ['locale' => implode('|', array_keys(config('translatable.locales')))]
], function () {
Route::get('page', function ($locale) {
return view(Helper::getLocaleView($locale, 'page'));
});
Route::get('home', function ($locale) {
return view(Helper::getLocaleView($locale, 'home'));
});
});
Route::get('/', function () {
return redirect()->to('en/home');
});
LanguageController:
class LanguageController extends Controller
{
public function postChangeLanguage(Request $request)
{
$changeLang = $request->input('lang');
$userLang = app()->getLocale();
if ($userLang !== $changeLang && array_key_exists($changeLang, config('translatable.locales')))
{
session(['locale' => $changeLang]);
app()->setLocale($changeLang);
}
return redirect()->back();
}
}
SetLocale middleware:
class SetLocale
{
public function handle($request, Closure $next)
{
if ($request->method() === 'GET')
{
$requestLocale = $request->segment(1);
if (array_key_exists($requestLocale, config('translatable.locales')))
{
session(['locale' => $requestLocale]);
}
else if (!session()->has('locale'))
{
$browserLanguage = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
if (array_key_exists($browserLanguage, config('translatable.locales')))
{
session(['locale' => $browserLanguage]);
}
else
{
session(['locale' => config('translatable.fallback_locale')]);
}
}
app()->setLocale(session('locale'));
}
return $next($request);
}
}
LocaleRedirect middleware:
class LocaleRedirect
{
public function handle($request, Closure $next)
{
$requestLocale = $request->segment(1);
$userLocale = session('locale');
if ($requestLocale !== $userLocale)
{
$segments = $request->segments();
array_shift($segments);
array_unshift($segments, $userLocale);
return redirect()->to(implode('/', $segments));
}
return $next($request);
}
}
setlocale
andlocale-redirect
to the correct classes in theApp\Http\Kernel
under$routeMiddleware
? – Azeame