Hi everyone,

I am new to Drupal 8 and drupal development in general. I am currently working on a project using the latest verion of Drupal 8.6.

I have written a custom module by following the drupal guides and everything works.

I now need to add a "tab" to the user profile page that links to my module. It should look something like this :

https://i.stack.imgur.com/7FMbs.jpg

I have created the corresponding task and routing files with the route and task definitions as such (replaced actual variable names with dummy values) :

my_module.routing.yml

my_module.some_route_name:
  path: '/user/{user}/some_path'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyModuleController::content'
    _title: 'Some Title'
  requirements:
    _permission: 'access content'
  options:
    user: \d+

my_module.links.tasks.yml

my_module.some_task_name:
  route_name: my_module.some_route_name
  base_route: entity.user.canonical
  title: 'Some Title'

I mostly followed the guides on the drupal documentation. This creates the route and the route path works when I type it in manually into the address bar. However, when I navigate to the user profile page, there is no tab.

So to solve this, I have created a hook in my my_module.module file (by referencing the Drupal 8.6 api) to add the tab to the user profile page like so :

function my_module_menu_local_tasks_alter(&$data, $route_name, \Drupal\Core\Cache\RefinableCacheableDependencyInterface &$cacheability) {

$url = Drupal\Core\Url::fromRoute('my_module.some_route_name');

if ($route_name == 'entity.user.canonical') {
$data['tabs'][0]['my_module.some_route_name'] = [
    '#theme' => 'menu_local_task',
    '#link' => [
    'title' => t('Some Title'),
    'url' => $url,
    'localized_options' => [
        'attributes' => [
        'title' => t('Add content'),
        ],
    ],
    ],
];

// The tab we're adding is dependent on a user's access to add content.
$cacheability
    ->addCacheTags([
    'user.permissions',
]);
}
}

I have modified it slightly to only add the tab when I am on the user profile page...
Finally, this works and creates the tab, however, the above code only works if I remove the {user} route from my route path and replace it with the actual user id
e.g. path: '/user/1/some_path'.

If I leave it as is e.g. path: '/user/{user}/some_path' , I get the following error on the website :

The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\Routing\Exception\MissingMandatoryParametersException</em>: Some mandatory parameters are missing (&quot;user&quot;) to generate a URL for route ...

I have also made sure to pass the correct parameters to my Controller method as described in the documentation here : https://www.drupal.org/docs/8/api/routing-system/using-parameters-in-routes

Any help or advice to point me into the right direction will be greatly appreciated.

Thanks

Comments

janpan’s picture

I fixed the problem by adding the parameter to my route in the menu_local_tasks_alter hook.

E.g.

$user = Drupal::currentUser();
$url = Drupal\Core\Url::fromRoute('my_module.some_route_path', ['user' => $user->id()]);

and also, I had to make sure that the paramter is also in my controller like so :

class myController extends ControllerBase {

//..
//..

  public function content(AccountInterface $user = NULL, Request $request) {

  //* do whatever you have to here *//

  }
}

Actually, I have tested and adding those parameters as per documentation, is not necessary at all. You only need a paramter that has the same name as specified in your route, in my case, this will result as $user.

Anyways, both options will work. 

dipali.goel25’s picture

Kindly navigate as it has very good example :

https://www.webwash.net/custom-tab-user-profile-page-views-drupal-8/

JFKiwad’s picture

It would be my_module.links.task.yml, not my_module.links.tasks.yml

strykaizer’s picture

It should be "my_module.links.task.yml", not plural tasks
 

sarikawirtz’s picture

Hi, you can use the view to get expected result. You must remove 's from tasks' file name "my_module.links.tasks.yml". You can also find a very good example here as well. Best of luck