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
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.
Explanation: This custom route provider defines a new route named example.landing_date with the desired path, defaults, requirements, and options. It extends NodeRouteProvider to leverage the existing node routing mechanisms.
2. Create a Custom Controller:
Create a custom controller class to handle the route:
PHP
namespace Drupal\your_module\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\RendererInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; 1. github.com github.com
class YourController extends ControllerBase {
protected $renderer;
public function __construct(RendererInterface $renderer) {
$this->renderer = $renderer;
}
public 1. github.com github.com function example(NodeInterface $node, $month_day) {
// Render the node and pass the 'month_day' argument to the block
$node_render = $this->renderer->render($node);
// Render the block with the 'month_day' argument
$block_render = $this->renderer->render([
'#theme' => 'your_block',
'#month_day' => $month_day,
]);
// Assemble the page content
$page = [
'#type' => 'page',
'#title' => $node->getTitle(),
'node' => $node_render,
'block' => $block_render,
];
return $page;
}
}
Explanation: This controller retrieves the node and renders it. It then renders the block, passing the month_day argument. Finally, it assembles the page content using the rendered node and block.
3. Create a Custom Block:
Create a custom block to display the dynamic content based on the month_day argument:
PHP
namespace Drupal\your_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; 1. drupal.stackexchange.com drupal.stackexchange.com
/**
* Provides a custom block.
*
* @Block(
* id = "your_module_block",
* admin_label = @Translation("Your Module Block"),
* )
*/
class YourModuleBlock extends BlockBase implements ContainerFactoryPluginInterface {
public function __construct(ContainerInterface $container) {
parent::__construct($container);
}
public function build() {
$month_day = $this->getContextValue('month_day');
// Use the 'month_day' argument to generate dynamic content
$content = "Dynamic content based on month_day: " . $month_day;
return [
'#markup' => $content,
];
}
}
Explanation: This block retrieves the month_day argument from the context and uses it to generate dynamic content.
Additional Notes:
Ensure that your custom module is enabled and that the route is defined in your module’s routing file.
You can further customize the block’s content and layout based on your specific requirements.
Consider using a theme layout to arrange the node and block elements on the page.
By following these steps, you’ll be able to effectively pass arguments to blocks within a Drupal 10 route and create dynamic content.