当用views创建page时,定义像'node/%node/foo'这样的路径,然后创建一个menu tab,在context filter里提供当前node页面的id作为默认参数,并开启参数验证:node type必须为article等。
当访问node/123/foo时,如果该node type不是article,会返回404等(根据设置),但menu tab依旧存在。
相关issue链接:
View argument validators are not taken into account in access checks
Views argument validators aren't taken into account on access checks - local task point to 404
暂时未有完美的patch,已推后至计划在drupal8.8.x-dev版本解决。
目前只有通过自定义模块去更替views建立的route配置
这也是通用的类似drupal 7的hook_menu_alter()方法
RouteSubscriber.php
<?php
namespace Drupal\round_robin\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
/**
* Listens to the dynamic route events.
*/
class RouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
// Note that the second parameter of setRequirement() is a string.
if ($route = $collection->get('view.matches.page_2')) {
$route->setRequirement('_custom_access', 'Drupal\round_robin\Controller\RoundRobinController::access');
}
}
}
round_robin.services.yml
services:
round_robin.route_subscriber:
class: Drupal\round_robin\Routing\RouteSubscriber
tags:
- { name: event_subscriber }
Drupal\round_robin\Controller\RoundRobinController::access
......
//verify route access
public function access() {
$bundle = false;
$route = \Drupal::routeMatch();
$nid = $route->getParameter('node');
if (is_object($nid)) {
$node = $nid;
} else {
$node = \Drupal\node\Entity\Node::load($nid);
}
if ($node instanceof \Drupal\node\NodeInterface) {
$bundle = $node->bundle();
}
return AccessResult::allowedIf($bundle === 'league');
}
评论