user15739925
user15739925

Reputation: 35

How to pass arguments from route to Drupal node?

I know how to define a route in Drupal 10 and create the associated content through a controller. But what I want to do now is to break this content in several blocks that I assemble in a classic Drupal base page using Drupal's Layout feature. The problem is that I can't find how to pass some arguments that are necessary to create dynamic content in blocks.

What I tried is create a content page with node id 51079 and url alias 'example'. 'arg' is the variable I want to pass to blocks. Then I defined a route in a custom module

example.landing_date:
    #    path: "/node/{nid}/{arg}"
    path: "/example/{arg}"
    defaults:
        _controller: '\Drupal\node\Controller\NodeViewController::view'
        #        _entity_view: "node.full"
        _title: "Example"
        node: 51079
        month_day: NULL
    options:
        parameters:
            #           nid:
            #               type: entity:node
            arg:
                type: string
    requirements:
        _permission: "access content"
        arg: "[0-9]{2}-[0-9]{2}"

The commented lines are an alternative which leads to the same result. This approach has two problems: 1 - I have to use either aliased or non aliased url which complicates management in a multilingual context. 2- When I visit /example, it works as expected I have the base page and the blocks are displayed according to the default value of 'arg' (empty). But if I visit /example/03-09, the value of arg (03-09) is correctly passed to the blocks but the node is displayed under the title, i.e. the page title is duplicated.

I looked how routes are managed in core node module and I see that they are not defined in routing.yml file but inside a NodeRouteProvider class. Perhaps I should also define my route by extending the NodeRouteProvider class but I don't see how and where to do it.

Upvotes: 0

Views: 140

Answers (1)

user15739925
user15739925

Reputation: 35

Finally I came to a solution with alterRoutes, thanks to https://drupalsun.com/philipnorton42/2022/10/16/drupal-9-altering-routes-route-subscriber-service

protected function alterRoutes(RouteCollection $collection) {

    /** @var \Symfony\Component\Routing\Route $augmented_node_route */
    $augmented_node_route = $collection->get('entity.node.canonical');
    $augmented_node_route->setPath('/node/{node}/{arg}');
    $augmented_node_route->addDefaults(['arg' => NULL]);
    $augmented_node_route->addOptions([
      'parameters' => [
        'arg' => ['type' => 'string']
      ]
    ]);
    $augmented_node_route->setRequirement('arg', '[0-9]{2}-[0-9]{2}');
}

By setting 'arg' default to NULL this permits to access '/node/{node}' as well (without 'arg')

What I don't understand is why when I try to achieve the same but with "new Route" in the same alterRoutes function (instead of altering the original route) it doesn't work or more precisely it works but duplicating the node title and without direct access to usual node tabs (edit, delete, revisions, etc.)

$route = new Route('/page/{node}/{arg}');
$route->addDefaults([
  '_controller' => '\Drupal\node\Controller\NodeViewController::view',
  '_title' => 'Page added through route subscriber',
]);
$route->addRequirements(
  [
    '_entity_access' => 'node.view'
  ]
);
$collection->add('myModule.node.canonical', $route);

Upvotes: 0

Related Questions