6

I've been looking all over online and can't find anything that tells you how to assign multiple routes to one callback. For example I want to move:

$app->get('/sign-in', function($request, $response) {
    return $this->view->render($response, 'home.twig');
});

$app->get('/login', function($request, $response) {
    return $this->view->render($response, 'home.twig');
});

into something like:

$app->get(['/sign-in', '/login'], function($request, $response) {
    return $this->view->render($response, 'home.twig');
});

Is there a way to do this with Slim 3? I found online that in Slim 2 you could use the conditions([]); function on the end to chain multiple routes to one callback.

Joe Scotto
  • 8,050
  • 7
  • 41
  • 100
  • 1
    Since you're already using an MVC-like structure, have you considered using a controller instead of putting closures in the routes file directly? – Bytewave Mar 28 '17 at 01:04
  • @Bytewave I'm quite new to this whole type of structure, would you mind explaining in a bit more detail what you mean? Maybe provide a code example? Thanks! – Joe Scotto Mar 28 '17 at 01:06
  • Controllers are a bit hard to explain in a comment, but I'll give it a go in an answer. – Bytewave Mar 28 '17 at 01:13
  • @Bytewave Thanks, I really appreciate it! – Joe Scotto Mar 28 '17 at 01:14
  • Actually, reviewing your comments on the other answer, I'm not sure that's the way to go about things. I would recommend using controllers anyway, to keep your logic separate and to help keep you organized, but it may not be relevant. I'm not sure there's a way of doing it with just an array of route paths---seems you'd have to do it with repeated `->get()` calls. – Bytewave Mar 28 '17 at 01:24
  • The way that Steve described could work, it's not the cleanest but definitely makes it a lot easier to modify all the code at once. – Joe Scotto Mar 28 '17 at 01:26
  • I'm afraid that's the cleanest it would get. Though, again, look into controllers if you want to keep your logic clean and separate. [Codecourse has a tutorial on Slim 3 controllers](https://www.codecourse.com/lessons/slim-3-controllers/533), but it seems you have to have an account to view the full series and I forget if CC is paywalled. – Bytewave Mar 28 '17 at 01:29

4 Answers4

4

It seems that you can simply define an array and loop through it to create multiple routes on one funciton.

$routes = [
    '/',
    '/home', 
    '/sign-in',
    '/login',
    '/register',
    '/sign-up',
    '/contact'
];

foreach ($routes as $route) {
    $app->get($route, function($request, $response) {
        return $this->view->render($response, 'home.twig');
    });
}
Joe Scotto
  • 8,050
  • 7
  • 41
  • 100
  • This would certainly work, so +1. Though i personally find it less intuitive than explicit routes with a shared function / method. – Steve Mar 28 '17 at 01:41
  • @Steve yeah. I see the benefits to both methods. I prefer the one I found because with my application I can simply add a new route to the array and it's done instead of having to create another get. – Joe Scotto Mar 28 '17 at 01:51
3

Just create the function as a closure and pass it as a parameter:

$home = function($request, $response) {
    return $this->view->render($response, 'home.twig');
};

$app->get('/sign-in', $home);

$app->get('/login',   $home);

Or use a named function:

function home($request, $response) {
    return $this->view->render($response, 'home.twig');
};
$app->get('/sign-in', 'home');

$app->get('/login',   'home');
Steve
  • 19,825
  • 5
  • 37
  • 61
  • This could very easily work but I would prefer a way where I could just pass an array of routes to `$app->get()`. Is this even possible? – Joe Scotto Mar 28 '17 at 01:20
  • Not a frequant Slim user, so i can only point your here: http://stackoverflow.com/questions/11521264/multiple-routes-with-the-same-anonymous-callback-using-slim-framework but personally i prefer to have explicit routes, even if they share a callback ( or indeed controller method as suggested by @Bytewave ) – Steve Mar 28 '17 at 01:27
  • FYI @Steve, that question/answer is for Slim 2, and unfortunately no longer relevant. – Bytewave Mar 28 '17 at 01:30
  • @Bytewave yes, thats always an issue when replying without current framework knowledge. Hopefully someone else can contribute an alternative, though i stand by my preference for explicit routes, regardless of framework or programming language – Steve Mar 28 '17 at 01:37
0

FastRoute doesn't do what you want, however, you can use a parameter that is limited via regex to the list of urls that you want to use:

$app->get("/{_:sign-in|login}", function ($request, $response) {
    $response->write("Hello!");
    return $response;
});

Note that you have to have an argument name, so I've use _ as it's inoffensive.

Rob Allen
  • 12,444
  • 1
  • 35
  • 46
-1

I am using regex to do this trick:

$app->get('/{router:login|sign-in}', function ($request, $response, $args) {
  echo "Hello, " . $args['router'];
});
Jiyu
  • 1