0

I have 2 node content types / bundles, A and B. each A has a relationship with multiple Bs. When on the edit page, node/%/edit, for A, I want to show a link to the list of related B so that an editor can easily see a prefiltered list of B for A.

I have created a route:

in my_module.routing.yml

my_module.related_B:
  path: '/node/{node}/related_b'
  base_route: entity.node.canonical
  options:
    _admin_route: TRUE

and have configured a view page at the same url node/%/related_b that contextually filters porperly. no issues there.

The link is added to the menu via the my_module.links.task.yml

my_module.related_B:
  route_name: my_module.related_B
  title: 'Related B'
  base_route: entity.node.canonical
  weight: 100

Everything shows up and looks/works the way I want it to.

related B example

The problem is that I cannot seem to figure out how to limit that link/view to only show and work when on the edit page for an instance of content A. It shows on EVERY node edit page.

I've tried the following and did not seem to get anywhere:

  • trying to hook into hook_local_tasks_alter in my_module.module
  • custom RouteSubscriber Plugin

In D7 I was abel to accomplish this with a hook and access callback:

function my_module_menu()
{
    $items = array();

    // Single sync functionality
    $items['node/%node/related_B'] = array(
        'title' => 'Related B',
        'page callback' => '_B_page_callback',
        'page arguments' => array(1),
        'access callback' => '_B_access_callback',
        'access arguments' => array(1),
        'type' => MENU_LOCAL_TASK,
    );

    return $items;
}

function _A_access_callback($node)
{
    if($node->type == 'A' && user_access('administer nodes'))
    {
        return TRUE;
    }

    return FALSE;
}
1
  • I think it is possible to create such a link with Views (without custom code).
    – ya.teck
    Commented Jul 16, 2019 at 9:25

1 Answer 1

0

I solved this. I mentioned that I had tried hook_local_tasks_alter when I should have been using hook_menu_local_tasks_alter

/**
 * Implements hook_menu_local_tasks_alter().
 * @param $local_tasks
 * @param $route_name
 * @param RefinableCacheableDependencyInterface $cacheability
 */
function mymodule_menu_local_tasks_alter(&$local_tasks, $route_name, RefinableCacheableDependencyInterface &$cacheability)
{
  if ($route_name == 'entity.node.edit_form') {
    $route_match = \Drupal::routeMatch();
    $node = $route_match->getParameter('node');

    if ('A' != $node->bundle()) {
      unset($local_tasks['tabs'][0]['my_module.related_B']);
    }
  }
}
1
  • You have to add a cache context: $cacheability->addCacheContexts(['route']);, otherwise this won't work in production when caching is enabled. BTW if you want to solve this the same way as now in D7 add a custom access check to the route, see drupal.org/docs/8/api/routing-system/access-checking-on-routes/…
    – 4uk4
    Commented Jul 15, 2019 at 18:25

Your Answer

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

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