【问题标题】:Create custom menu tab on a users profile page in Drupal 8在 Drupal 8 中的用户个人资料页面上创建自定义菜单选项卡
【发布时间】:2018-10-10 12:13:46
【问题描述】:

我是 Drupal 新手。我在 Drupal 8 中编写了一个自定义模块,它可以工作并显示一些内容。

我想在用户的个人资料中添加一个链接到我的自定义模块的选项卡。

据我了解,我需要写一条路线和一个任务。这就是我所做的:

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'

我已完成此操作,并且路由正常运行,但是在我的用户的个人资料页面中没有标签显示

它应该看起来像这样:

编辑 1

我通过根据 Drupal API 8.6 (menu_local_tasks_alter) 创建一个钩子部分解决了这个问题,这就是我写的:

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',
]);
}

}

如果我将路径路径的 {user} 部分替换为 1,则此方法有效。当路径中有 {user} 时,它现在会抱怨以下错误:

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 ...

编辑 2

我还确保在我的控制器中为我的内容方法提供一个用户对象 $user,该对象实现了如下所述的 AccountInterface:https://www.drupal.org/docs/8/api/routing-system/using-parameters-in-routes,但是,我仍然收到相同的错误消息。

【问题讨论】:

    标签: drupal drupal-modules drupal-8


    【解决方案1】:

    如果将来有人偶然发现此问题,这里有一种更简单的方法,不需要 HOOK_menu_local_tasks_alter 实现,并更正了 OP 代码中的错字:

    my_module.routing.yml

    entity.my_entity.my_route:
      path: '/admin/my_entity/{my_entity}/my_route' # Or similar
      defaults:
        _controller: '\Drupal\my_module\Controller\MyController::content'
        _title: 'My Route Title'
      options:
        parameters:
          my_entity:
            type: entity:my_entity
      requirements:
        _permission: 'my_permission'
    

    my_module.task.yml

    请注意 OP 帖子中的单数 task 而不是 tasks

    entity.my_entity.my_route:
      route_name: entity.my_entity.my_route
      base_route: entity.my_entity.canonical
      title: 'My Route Title'
    

    然后像在@cesar-moore 的帖子中那样编写您的控制器,正如他所说,将第一个参数向上转换为MyEntity $my_entity。无需任何改动。此路由现在将在您实体的每个页面上显示一个新选项卡:查看、编辑或类似。

    【讨论】:

      【解决方案2】:

      你不需要钩子,我只是用你的 routing 和 _task 定义进行了测试,它对我来说很好。

      这是我的控制器:

      class MyModuleController {
      
        public function content($user) {
          return [
            '#markup' => "user: $user"
          ];
        }
      
      }
      

      这在“/user/1/some_path”URL 处呈现为:“user: 1”。

      我认为您也在尝试使用Drupal's automatic paramater upcasting,但这是可选的。

      MissingMandatoryParametersException

      解决异常(Symfony\Component\Routing\Exception\MissingMandatoryParametersException)。 您必须在路由中添加强制参数。只需添加用户(['user' =&gt; 1]):

      $url = Drupal\Core\Url::fromRoute('my_module.some_route_name', ['user' => 1]);
      

      【讨论】:

      • 是的!谢谢这个作品。我将其更改为像这样获取当前登录用户: $user = Drupal::currentUser(); $url = Drupal\Core\Url::fromRoute('my_module.some_route_name', ['user' => $user->id()]);
      • 谢谢,我正忙着检查能不能去掉钩子。
      • 谢谢,我已经从我的控制器中删除了附加参数,正如你所解释的那样没有简化。但是,看来我仍然需要钩子,否则本地任务/选项卡不会作为选项卡之一显示在我的用户个人资料页面中......无论如何,你帮了我很多!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多