phplaravelrouteswildcardlaravel-3

Laravel - Using (:any?) wildcard for ALL routes?


I am having a bit of trouble with the routing.

I'm working on a CMS, and I need two primary routes. /admin and /(:any). The admin controller is used for the route /admin, and the view controller should be used for anything else than /admin. From the view controller, I will then parse the url and show the correct content.

This is what I have:

Route::get(array('admin', 'admin/dashboard'), array('as' => 'admin', 'uses' =>'admin.dashboard@index'));
Route::any('(:any)', 'view@index');

The first route works, but the second one doesn't. I played around with it a little bit, and it seems if I use (:any) without the question mark, it only works if I put something after /. If i do put the question mark there, it doesn't work at all.

I want all of the following routes to go to view@index:

/
/something
/something/something
/something/something/something
/something/something/something/something
...etc...

Is this possible without hardcoding a bunch of (:any?)/(:any?)/(:any?)/(:any?) (which I don't even know works)?

What's the best way to go about this?


Solution

  • Edit: There has been some confusion since the release of Laravel 4 regarding this topic, this answer was targeting Laravel 3.

    There are a few ways to approach this.

    The first method is matching (:any)/(:all?):

    Route::any('(:any)/(:all?)', function($first, $rest=''){
        $page = $rest ? "{$first}/{$rest}" : $first;
        dd($page);
    });
    

    Not the best solution because it gets broken into multiple parameters, and for some reason (:all) doesn't work by itself (bug?)

    The second solution is to use a regular expression, this is a better way then above in my opinion.

    Route::any( '(.*)', function( $page ){
        dd($page);
    });
    

    There is one more method, which would let you check if there are cms pages even when the route may have matched other patterns, provided those routes returned a 404. This method modifies the event listener defined in routes.php:

    Event::listen('404', function() {
        $page = URI::current();
        // custom logic, else
        return Response::error('404');
    });
    

    However, my preferred method is #2. I hope this helps. Whatever you do, make sure you define all your other routes above these catch all routes, any routes defined after will never trigger.