Adding local task tabs to node display for specific content type I'm creating a custom module (it's called cil_meet) which adds two content types (organisation and room).  On an organisation node I want a local task tab (next to 'view' and 'edit') of 'add room', for administrators.  On a room node I want two tabs 'publish' and 'info'.

After some research, I've figured out a way to achieve this, but I want to know if there is a better way of doing this?

cil_meet.routing.yml:

cil_meet.addroom:
  requirements:
    _role: 'administrator'
cil_meet.roompublish: 
#  path: '/meet/{organisation}/{room}/publish'
  requirements:
    _role: 'authenticated'
cil_meet.roominfo: 
#  path: '/meet/{organisation}/{room}/info'
  requirements:
    _role: 'authenticated'


I've commented out the path for publish &amp; info for now - I'll set up controllers, etc later.

cil_meet.links.task.yml:

cil_meet.addroom: 
  route_name: 'node.add' 
  title: 'Add Room'
  weight: 100
  route_parameters:
    node_type: 'room'
  base_route: entity.node.canonical
cil_meet.roompublish: 
  route_name: 'cil_meet.roompublish' 
  title: 'Publish'
  weight: 100
  base_route: entity.node.canonical
cil_meet.roominfo: 
  route_name: 'cil_meet.roominfo' 
  title: 'Info'
  weight: 101
  base_route: entity.node.canonical


This adds the tabs to all nodes.  So to remove the tabs from anything other than organisation or room nodes, I've got to add some code to the module.

cil_meet.module:

&lt;?php
/**
 * Implements hook_local_tasks_alter().
 */
function cil_meet_menu_local_tasks_alter(&amp;$local_tasks, $route_name) {
    $route_match = \Drupal::routeMatch();

    if ($route_match-&gt;getRouteName() == 'entity.node.canonical') {
        $node = $route_match-&gt;getParameter('node');
        if($node-&gt;bundle()!='organisation') {
            unset($local_tasks['tabs'][0]['cil_meet.addroom']); 
        }

        if($node-&gt;bundle()!='room') {
            unset($local_tasks['tabs'][0]['cil_meet.roompublish']);
            unset($local_tasks['tabs'][0]['cil_meet.roominfo']);
        }
    }
}


All works as expected, the above may help others needing a similar solution.  Is there a better way of doing this?
Solution from Matt B only hides the tab on the node view page, but not on the node edit etc. The direct url will also be accessible in that case.

A better solution is to write a custom access handler

See Custom validation of route parameters