1
votes

I use this guide: https://mydnic.be/post/how-to-build-an-efficient-and-seo-friendly-multilingual-architecture-in-laravel-v2

I have these routes and middleware:

$locale = request()->segment(1);

Route::middleware('localized')->prefix($locale)->group(function() {
     Route::get('/contacts', 'ContactController@index');
     Route::get('/page/{page}', 'PageController@index');
});

And middleware localized from Kernel.php -> routeMiddleware:

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
        $segments = $request->segments();

        $segments = Arr::prepend($segments, config('app.fallback_locale'));

        if($request->session()->has('language')) {
            $segments[0] = session('language');
        }

        return redirect()->to(implode('/', $segments));
    }
    
    return $next($request);
}

When I access to: site.test/contacts he redirect me on locale: site.com/en/contacts When I access to site.test/page/test I got 404 not found, If I access to: site.com/en/page/test then page working. Problem with redirect on locale with route model binding.

In Controller Page I have:

public function index(Page $page) 
{
    return view('page', compact('page'));
}

In translatable.php:

'locales' => [
    'de' => 'Deutsch',
    'en' => 'English',
],

In AppServiceProvider:

public function boot()
{
    if(array_key_exists(request()->segment(1), config('translatable.locales'))) {
        app()->setLocale(request()->segment(1));
    }
}
1
Are you sure the above example code works? as I'm trying to replicate "When I access to: site.test/contacts he redirect me on locale: site.com/en/contacts" but it's not working for me unless I add the locale site.test/fr/contacts .. then it works. How is your translatable.php config file setup?Kolawole Emmanuel Izzy
@KolawoleEmmanuelIzzy I updated my question with config and provider. Yep my code worksRed Fox

1 Answers

0
votes

I was able to work around this but this cost us access to the session, which you checked for to know if the session has "language" if yes, then prepend locale value should be set to the language value in the session. Below is what I did;

In Routes File

$locale = request()->segment(1);

Route::prefix($locale)->group(function() {
     Route::get('/contacts', function(){
         echo "hello contact";
     });
     Route::get('/page/{page}', function(Request $request, $page){
        return "hello Page {$page}";
     });
});

In MiddleWare File I did

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // Remove the session check as we don't have access to session yet
    /*if($request->session()->has('language')) {
        $segments[0] = session('language');
    }*/

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}

Now in Kennel.php File for Middleware, Add your middleware class in the $middleware array

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];

Then try access site.test/page/1000 ... it will be redirected to site.test/{app.fallback_locale}/page/1000. In my case site.test/en/page/1000

UPDATE

After reading through this issue on git for laravel, I then thought of adding the session before the Localized middle class and it worked. I'm not sure if this is good practice but it got the job done.

In MiddleWare File I did

public function handle(Request $request, Closure $next)
{
    if (!array_key_exists($request->segment(1), config('translatable.locales'))) {
    $segments = $request->segments();

    $segments = Arr::prepend($segments, config('app.fallback_locale'));
    
    // We can have session back on
    if($request->session()->has('language')) {
        $segments[0] = session('language');
    }

    return redirect()->to(implode('/', $segments));
}

    return $next($request);
}

Now in Kennel.php File for Middleware, Add Session middleware before Localized Middleware class

/**
 * The application's global HTTP middleware stack.
 *
 * These middleware are run during every request to your application.
 *
 * @var array
 */
protected $middleware = [
    ...
    \Illuminate\Session\Middleware\StartSession::class,
    \App\Http\Middleware\Localized::class, //This is the Localized Middlewere class
];