How can I customize controller output based on developer supplied parameters with Laravel 8?

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.

edit:

I tried the defaults() method and it works well. Note that in order for it to work, a separate default() call has to be made for each function parameter. For example:

Route::get('/login/main', [WAYFController::class, 'wayf'] )
    ->defaults('tiledUI', false)
    ->defaults('showAffiliateLogin', true)
    ->defaults('type', 'full');

Upvotes: 0

Views: 71

Answers (1)

lagbox
lagbox

Reputation: 50511

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');

Upvotes: 1

Related Questions