Skip to content
Advertisement

How to remove route prefix from route actions in Laravel

I am creating localization in Laravel 5.3 application. It must follow such requirements:

  1. If route path contains locale prefix, locale should be set according to this prefix

  2. If there’s no route prefix, it should be set to English.

For instance:

A) mysite.org/pl/blog/133 sets locale to pl and calls BlogController with parameter 113

B) mysite.org/en/blog/133 sets locale to en and calls BlogController with parameter 113

C) mysite.org/blog/133 acts in the same way as previous.

To implement this, I was using the following code:

#routes/web.php

require base_path('routes/common.php');
// TODO set default locale to en

Route::group(['prefix' => '{locale}'], function($group) {

    require base_path('routes/common.php');
    // TODO set locale to $locale

    foreach ($group -> getRoutes() as $route) {
        $route->where('locale', 'en|ru|pl|ua|de');
    }

});


#routes/common.php

Route::get('/blog/{id}', function($id) {
    // Return view of respective blogpost
});

The problem is that when I use path A or B i get an extra first parameter in my action function, which derives from the locale prefix.

Can I hide this parameter somehow? Or is there a way to achieve what I want in a way more architecturally correct?

Advertisement

Answer

I’m not sure my solution is the best or not but you can try this

  1. create new file in app/Http/Middileware/Language.php

namespace AppHttpMiddleware;

use Closure;
use IlluminateRoutingRedirector;
use IlluminateHttpRequest;

class Language {

    public function __construct(Redirector $redirector) {
        // $this->app = $app;
        $this->redirector = $redirector;
        // $this->request = $request;
    }

    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Make sure current locale exists.
        $segments = $request->segments();
        $locale = $segments[0];

        $languages = ['en','ru','pl','ua','de'];
        if (!in_array($locale, $languages)) {
            $segments = array_merge(['en'], $segments);
            return $this->redirector->to(implode('/', $segments));
        }

        return $next($request);
    }

}
  1. In app/Http/Kernel.php and this line

    protected $middleware = [
        AppHttpMiddlewareLanguage::class,
    IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode::class,
    ];
    
  2. In file route (route/web.php) add prefix in group

    Route::group(['middleware' => ['web'], 'prefix' => '{locale}'],
    function ()      {
    ...
    

Hope this help

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement