3

Suppose I have the following route in my ej.routing.yml file:

ej.form.user.profile:
 path: '/user/{user}/ej_profile'
 defaults:
   _title: 'EJ Profile'
   _form: '\Drupal\ej\Form\User\ProfileForm'
 requirements:
   _role: 'authenticated'
   user: \d+

Now I want to add a menu based on the above route to Tools menu. So I use the following in ej.links.menu.yml file:

ej.user.profile:
  title: 'EJ Profile'
  description: 'EJ Profile'
  route_name: ej.form.user.profile
  menu_name: tools
  weight: 100

However this gives me an exception saying: Symfony\Component\Routing\Exception\MissingMandatoryParametersException: Some mandatory parameters are missing ("user") to generate a URL for route "ej.form.user.profile".

The same works as a task entry. Basically I have a custom form that extends user profile to integrate with a third-party system and I need the user id from the url to fetch appropriate user's information.

How can I have the menu to pick route parameter from the url?

3
  • I think that (out of the box) only local tasks and actions pick up route parameters from the current route.
    – Eyal
    Mar 13, 2017 at 1:31
  • 1
    You can try using a custom class for the menu item. And then add your route parameter as you like.
    – Eyal
    Mar 13, 2017 at 1:32
  • Do you want to add multiple menu items (one for each user in the DB)? Or do you want to add a single menu item (just for the current user)?
    – Eyal
    Jan 16, 2018 at 18:43

1 Answer 1

0

As @Eyal mentioned, "You can try using a custom class for the menu item. And then add your route parameter as you like."

I've done this by extending the MenuLinkDefault class and then assigning my menu link to use the class in my MY_MODULE.links.menu.yml.

For example my ExampleMenuLink class:

namespace Drupal\my_module\Plugin\Menu;

use Drupal\Core\Menu\MenuLinkDefault;

class ExampleMenuLink extends MenuLinkDefault {

  /**
   * Determine my dynamic parameter and add it to the route's parameters.
   */
  public function getRouteParameters() {
    $original_params = $this->pluginDefinition['route_parameters'] ?: [];

    $my_dynamic_params = [
      'example_param' => $this->getMyDynamicRouteParameter(),
    ];

    return $my_dynamic_params + $original_params;
  }

  /**
   * Disable my menu link if a real dynamic parameter can't be determined.
   */
  public function isEnabled() {
    // If we can't determine our route parameter, disable the link.
    if ($this->canDetermineMyRouteParameter() !== TRUE) {
      return FALSE;
    }

    return parent::isEnabled();
  }

}

Then, my MY_MODULE.links.menu.yml file:

my_module.my_custom_route_link:
  title: 'My Custom Link'
  route_name: my_module.my_custom_route
  route_parameters:
    example_param: 0 # Dynamically set in ExampleMenuLink.
  class: Drupal\my_module\Plugin\Menu\ExampleMenuLink

Since the route parameter is required, I could only get this to work by passing a dummy parameter in my link definition, e.g. example_param: 0. In my case, I was passing an entity id so 0 would never be valid. This parameter will never be used anyway because in the ExampleMenuLink::isEnabled() method, I disable the link if I can't get an appropriate value for my dynamic parameter. Additionally, I implement ExampleMenuLink::getRouteParameters() to add my dynamic parameter and pass it to the route.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.