In this Symfony route
/**
* @Route("/board/{board}/card/{card}", name="card_show", methods={"GET"}, options={})
*/
public function show(Board $board, Card $card): Response
{
$card->getLane()->getBoard(); // Board instance
// ...
}
How is it possible to add the {board}
parameter programatically, since it is already available in {card}
? Now, I always need to add two parameters, when generating links to show action.
After some research I've found the RoutingAutoBundle (https://symfony.com/doc/master/cmf/bundles/routing_auto/introduction.html#usage) which would provide the functions I need, but it's not available for Symfony 5 anymore.
Thanks.
Okay, after some investigation I've found this question Which lead me to this helpful answer.
My controller action (with @Route
annotation) looks like this:
/**
* @Route("/board/{board}/card/{card}", name="card_show", methods={"GET"})
*/
public function show(Card $card): Response
{
}
We just have one argument ($card
) in method signature, but two arguments in route.
This is how to call the route in twig:
path("card_show", {card: card.id})
No board
parameter required, thanks to a custom router.
This is how the custom router looks like:
<?php // src/Routing/CustomCardRouter.php
namespace App\Routing;
use App\Repository\CardRepository;
use Symfony\Component\Routing\RouterInterface;
class CustomCardRouter implements RouterInterface
{
private $router;
private $cardRepository;
public function __construct(RouterInterface $router, CardRepository $cardRepository)
{
$this->router = $router;
$this->cardRepository = $cardRepository;
}
public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH)
{
if ($name === 'card_show') {
$card = $this->cardRepository->findOneBy(['id' => $parameters['card']]);
if ($card) {
$parameters['board'] = $card->getLane()->getBoard()->getId();
}
}
return $this->router->generate($name, $parameters, $referenceType);
}
public function setContext(\Symfony\Component\Routing\RequestContext $context)
{
$this->router->setContext($context);
}
public function getContext()
{
return $this->router->getContext();
}
public function getRouteCollection()
{
return $this->router->getRouteCollection();
}
public function match($pathinfo)
{
return $this->router->match($pathinfo);
}
}
Now, the missing parameter board
is provided programatically, by injecting and using the card repository. To enable the custom router, you need to register it in your services.yaml:
App\Routing\CustomCardRouter:
decorates: 'router'
arguments: ['@App\Routing\CustomCardRouter.inner']