Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Routing: Catch-all #44

Open
telephone opened this issue Jun 2, 2014 · 5 comments
Open

Routing: Catch-all #44

telephone opened this issue Jun 2, 2014 · 5 comments

Comments

@telephone
Copy link

I feel a sub-section within routing should be devoted to displaying the correct way to provide a catch-all... Fat-Free doesn't provide a direct method for catch-all, so it may confuse new users. It's also one of the first things I do within a project to provide custom logic instead of a default 405.

Now personally I have two ways of achieving this, but I figured I'd ask everyone else to see if you guys have your own ways.

Method 1:

// known routes should be added before catch-all...

$f3->route('GET|HEAD|POST /*/*', function($f3) {
    //
    // add custom logic here....
    //

    // call F3 error handler for cases not matching custom logic
    $f3->error(405);
});

In my tests, "//" proved to work but I didn't use a full test suite with edge cases, so I'm unsure if it provides true catch-all support.
Using "//" also infers that a method has already caught all single parameter routes. E.g. /@action. With this said the wildcard may need to be at a proportional depth compared with existing routes.

Method 2:

I'm going to be lazy here, but it involves adding a custom error handler to catch 405 errors... I'll just provide an example from my error handler:

\Error::instance()->addHandler(405, function() use($f3) {
    // custom logic
    if (!$f3->get('AJAX') && in_array($f3->get('VERB'), array('GET', 'HEAD', 'POST'))) {
        $f3->reroute('/');
    }

    // call default F3 error handler (will pass on 405 error)
    call_user_func_array(array($f3, 'error'), $f3->get('ERROR'));
});

That's about it. Let me know your thoughts, or if you have an alternative method (we can pick which one is best suited) :)

@xfra35
Copy link
Member

xfra35 commented Jun 3, 2014

In the first method, isn't a single wildcard enough? => GET|HEAD|POST /*

@telephone
Copy link
Author

In the first method, isn't a single wildcard enough? => GET|HEAD|POST /*

No, as the single wildcard will take precedence over any single level routes.

E.g.

$f3->route('GET|HEAD|POST /', 'Home->controller');
$f3->route('GET|HEAD|POST /@action', 'Home->@action');

// wildcard will take precedence over the two routes above
$f3->route('GET|HEAD|POST /*', 'Home->catchAll');

@xfra35
Copy link
Member

xfra35 commented Jun 4, 2014

You're right. I didn't expect that behaviour. I wonder if it is intended or if it is a bug..

@xfra35
Copy link
Member

xfra35 commented Jun 4, 2014

Well the doc says:

An important point to consider: You will get Fat-Free (and yourself) confused if you have both GET /brew/@count and GET /brew/* together in the same application. Use one or the other.

@Microgamer
Copy link
Contributor

On my sites I use something like this
users/new
/users/@nickname
Both as GET and it works very well.
I like it like it is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants