I had some issues with the Menu Token module, so I looked into an alternative. I found that there is an easy way to add dynamic components in menu links. Let's say that you are creating a webshop with Drupal Commerce and that you want to create a link to the user's orders. The link would have to look something like this:
/user/{{ currentUserID }}/orders
As you can probably guess, {{ currentUserID }} is a dynamic component. Each user has a different ID. You can create such a link by creating two files inside your custom module.
First, you need to create a my_module.links.menu.yml file in the root directory of your module:
my_module.user_orders:
weight: -50
menu_name: account
class: Drupal\my_module\Plugin\Menu\UserOrdersMenuLink
As you can see this link will appear in the User account menu. The link path is generated in the UserOrdersMenuLink class. Let's see how that class looks like:
<?php
namespace Drupal\my_module\Plugin\Menu;
use Drupal\Core\Menu\MenuLinkDefault;
use Drupal\Core\Menu\StaticMenuLinkOverridesInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
class UserOrdersMenuLink extends MenuLinkDefault {
protected $currentUser;
public function __construct(array $configuration, $plugin_id, $plugin_definition, StaticMenuLinkOverridesInterface $static_override, AccountInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $static_override);
$this->currentUser = $current_user;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('menu_link.static.overrides'),
$container->get('current_user')
);
}
public function getTitle() {
return $this->t('My Orders');
}
public function getUrlObject($title_attribute = TRUE) {
return Url::fromUri('internal:/user/' . $this->currentUser->id() . '/orders');
}
}
And that's it. Clear the cache and go to the user menu: Structure -> Menus -> User account menu. You should see your new dynamic link there.
Please note that Drupal 8 adheres to PSR-4. This means that files must be named in certain ways and placed in specific folders. Here is what the module structure should look like:
my_module
├── my_module.info.yml
├── my_module.links.menu.yml
└── src
└── Plugin
└── Menu
└── UserOrdersMenuLink.php