Question: Laravel: Best way to implement dynamic routing in routes.php based on environment variable?


Laravel: Best way to implement dynamic routing in routes.php based on environment variable?

Answers 2
Added at 2016-12-31 09:12

My aim is to roll out a big re-theming / re-skinning (including new URL routing) for a Laravel v5 project without touching the existing business logic (as much as possible that is).

This is my current approach:

  1. I placed a APP_SKIN=v2 entry in my .env file

  2. My app\Http\routes.php file has been changed as follows:

    if (env('APP_SKIN') === "v2") {
        # Point to the v2 controllers
        Route::get('/', 'v2\GeneralController@home' );
        ... all other v2 controllers here ...
    } else {
        # Point to the original controllers
        Route::get('/', 'GeneralController@home' );
        ... all other controllers
  3. All v2 controllers have been placed in app/Http/Controllers/v2 and namespaced accordingly

  4. All v2 blade templates have been placed in resources/views/v2
  5. the rest of the business logic remains exactly the same and shared between the "skins".

My question: Is there a "better" way to achieve the above?. Please note that the idea here is to affect as few files as possible when doing the migration, as well as ensure that the admin can simply change an environment variable and "roll back" to the previous skin if there are problems.

nr: #1 dodano: 2016-12-31 11:12

Routes pass through Middleware. Thus you can achieve this by BeforeMiddleware as follows

public function handle($request, Closure $next)
  // Get path and append v2 if env is v2
  $path = $request->path();
  $page = $str = str_replace('', '', $path); // You can replace if neccesary

  // Before middleware
  if (env('APP_SKIN') === "v2")
      return $next($request);  
nr: #2 dodano: 2016-12-31 14:12

Within app/Providers/RouteServiceProvider.php you can define your routes and namespaces, etc. This is where I would put the logic you talked about (rather than in the routes file):

protected function mapWebRoutes()
    if (App::env('APP_SKIN') === 'v2') {
            'middleware' => 'web',
            'namespace' => $this->namespace,
        ], function ($router) {
            require base_path('routes/web_v2.php');
    } else {
        // ...

This way, you can create separate route files to make it a bit cleaner.

Aside from that, I personally can't see a better solution for your situation than what you described as I'm guessing your templates want to vary in the data that they provide, which if that is the case then you will need new controllers - otherwise you could set a variable in a middleware which is then retrieved by your current controllers which could then determine which views, css and js are included. This would mean you would only need to update your existing controllers, but depending upon your current code - this could mean doing just as much work as your current solution.

Source Show
◀ Wstecz