Home > Mobile >  Laravel 8 - Customize controller output based on developer supplied parameters
Laravel 8 - Customize controller output based on developer supplied parameters

Time:12-01

Is there any way to customize what a controller returns based on a parameter (not a query parameter) provided in a route? For example, if there are two modes of display, but it depends on the URL accessed as far as which way it's displayed.

A simplified, made up example:

class MyController extends Controller
{
    // $display_mode can be "large" or "small"

    public function show($display_mode = null)
    {
         ...
    }
}

Route:

For /page1 I want $display_mode to be "large", for /page2, I want it to be "small." How do I pass that in via the function parameter? This would be the preferred way, but if Laravel does this a different way, let me know.

Route::get('/page1', [MyController::class, 'show']);

Route::get('/page2', [MyController::class, 'show']);

To get a better idea of what I want to accomplish. Say the controller function has five different customizable parameters based on both display and business logic. I can't know in advance what options will apply to the pages that the developer creating routes will want to display. I just want to make those options available.

Also, the developer making the routes does not want to make URLs with ugly paths such as mypage/large/tiled/system-only. The end user doesn't need to know about all of the options passed in as parameters to a function.

Rather, the routes should only be /a, /b, and /c and each of those routes underneath the hood represents zero to five customizable options by passing in the options as parameters to the controller function.

CodePudding user response:

Yea, you can do this. You can use the defaults method of the Route to pass a default value for a parameter:

Route::get('testit', function ($display_mode) {
    dump($display_mode);
})->defaults('display_mode', 'large');

You can use this to pass arbitrary data to the 'action'.

Another use-case for this is if you had something like a PageController to display a single page but don't want the routes to be dynamic and instead explicitly define the routes you will have:

Route::get('about-us', [PageController::class, 'show'])
    ->defaults('page', 'about-us');

Route::get('history', [PageController::class, 'show'])
    ->defaults('page', 'our-history');

The Route class is Macroable so you could even create a macro to define these defaults on the route:

Route::get('about-us', [PageController::class, 'show'])
    ->page('about-us');

The Router itself is also Macroable so you could define a macro to define all of this into a single method call:

Route::page('about-us', 'about-us');
  • Related