symfonyroutessymfony-3.4symfony-cmf

Symfony CMF Dynamic Router no contentDocument


Following the Dynamic Router doc, I can:

But as my controller should expect the $contentDocument parameter, I have nothing.

Here's how I create my route and my entity:

    $page = new Page();
    $page->setTitle('My Content')
    ->setBackground(1)
    ->setDescription('My description')
    ->setContent('<h1>Hello</h1>');
    $manager->persist($page);
    $manager->flush(); // flush to be able to use the generated id

    $contentRepository = $this->container->get('cmf_routing.content_repository');

    $route = new Route();
    $route->setName('my-content');
    $route->setStaticPrefix('/my-content');
    $route->setDefault(RouteObjectInterface::CONTENT_ID, $contentRepository->getContentId($page));
    $route->setContent($page);
    $page->addRoute($route); // Create the backlink from content to route

    $manager->persist($page);
    $manager->flush();

Here's my config section:

cmf_routing:
    chain:
        routers_by_id:
            router.default: 200
            cmf_routing.dynamic_router: 100
    dynamic:
        enabled: true
        persistence:
            orm:
                enabled: true
        generic_controller: AppBundle:Default:showPage
        templates_by_class:
            AppBundle\Entity\Page: AppBundle:Default:index.html.twig

My controller:

public function showPageAction($page)
{
    return $this->render('default/index.html.twig');
}

And the error:

Controller "AppBundle\Controller\DefaultController::showPageAction()" requires that you provide a value for the "$page" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.


Solution

  • Dynamic routing puts the content document into the request with the name "contentDocument". You need to explicitly use that name:

    public function showPageAction($contentDocument)
    {
        return $this->render('default/index.html.twig');
    }
    

    if you do not need to do anything in your controller, you don't need to specify the generic_controller. template_by_class will make the bundle provided controller render that template with the page instance found in $contentDocument.