0

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 & 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:

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

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

        if($node->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?

  • 1
    Also, not that I need to do it, but a nice to have would be for the 'Add Room' tab to pre-populate the node add form with the organisation from the organisation node where the user has clicked on the tab. The Room content type has an entity reference field called 'field_organisation'. – Matt B Apr 14 at 7:24
  • 1
    I did something similar not too long ago. I think this is the right approach, you overwrite Drupal's behavior in your custom module with the recommended method and implement the right hook to only affect the content types you want. Kudos ! – seroton Apr 14 at 15:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.