Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5, Sub-Domain routing, with optional parameter

I’ve just started learning Laravel 5 and trying to create multilanguage web site and want to use different domains for the language so en.example.app points to English version, es.example.app to Spanish and so on. I use route groups and below is my code.

Route::group(['domain' => '{domain}.example.app'], function() {
    Route::get('/', function () {
        return view('index');
    });
    Route::get('test', function(){
        return view('index');
    });
});

It works fine for all domains except example.app. Unfortunately optional parameters {domain?} doesn’t work for subdomains, and I don’t want to duplicate routes like this.

Route::get('/', function () {
    return view('index');
});
Route::get('test', function(){
    return view('index');
});

Route::group(['domain' => '{domain}.example.app'], function() {
    Route::get('/', function () {
        return view('index');
    });
    Route::get('test', function(){
        return view('index');
    });
});

Could somebody please advise how to avoid this duplication?

like image 890
Teymur Avatar asked Aug 23 '15 21:08

Teymur


People also ask

What is subdomain routing in Laravel?

Subdomain routing is the same as routing prefixing, but it's scoped by subdomain instead of route prefix. There are two primary uses for this. First, you may want to present different sections of the application (or entirely different applications) to different subdomains.

What is Route :: has in Laravel?

The route is a way of creating a request URL for your application. These URLs do not have to map to specific files on a website, and are both human readable and SEO friendly. In Laravel, routes are created inside the routes folder. They are are created in the web.

How do you add a prefix in Laravel?

Route::group(['prefix'=>'admin'],function (){ Route::group(['prefix' => 'admin','middleware' => 'auth'], function () { Route::group(['prefix' => 'candidate','middleware' => 'auth'], function () { Route::get('login', 'frontend\LoginController@login'); Route::get('/home', 'DashboardController@index')->name('home');


3 Answers

Thats becuase the {domain}.example.app requires a . before example.app.

You can remove the . and add contraint for domain parameter for it to have atmost 1 .

So the code will look like

Route::group(['domain' => '{domain}example.app'], function($group) {
    Route::get('/', function ($domain) {
        //code
    }) ;
    // more routes

    foreach($group->getRoutes() as $route){
        $route->where('domain', '[a-z]+\.{0,1}');
    }

});

P.S. : I don't know whether my regex is correct or not.

like image 88
Kapil Garg Avatar answered Oct 20 '22 00:10

Kapil Garg


You could create a file named app-routes.php which contains all your routes and then in your actual routes.php file

Route::group(['domain' => '{domain}.example.app'], function() {
    include('app-routes.php');
}); 

Route::group(['domain' => 'example.app'], function() {
    include('app-routes.php');
}); 
like image 44
J. Davis Avatar answered Oct 19 '22 22:10

J. Davis


A MiddleWare helped me.

Route::group(array('middleware' => 'resolve_domain'), function () {
    Route::get('/', 'WhitePapersController@getHomepage');
});

And in MiddleWare -

public function handle($request, Closure $next)
{
    $params = explode('.', $request->getHost());
    $sub_domains = config('admin_configs.editions'); // Predefined sub-domain
    $edition = false;
    if(!empty($params[0]) && in_array($params[0], $sub_domains, true))  {
        $edition = $params[0];
    }
    define('DOMAIN_EDITION', $edition); // Set constant to be used.

    return $next($request);
}
like image 43
Sougata Bose Avatar answered Oct 20 '22 00:10

Sougata Bose