【问题标题】:Drupal module nested menu itemsDrupal 模块嵌套菜单项
【发布时间】:2009-12-09 04:08:48
【问题描述】:

在为模块实现hook_menu 时,我试图将一些项目放入子菜单中。

到目前为止,我有这样的东西

$items['MyModule'] = array(
  //...
  'page callback' => 'system_admin_menu_block_page',
  'file' => 'system.admin.inc',
  'file path' => drupal_get_path('module','system'),
);

$items['MyModule/MenuItem1'] = array(
  //...
);

$items['MyModule/SubMenu'] = array(
  //...
  'page callback' => 'system_admin_menu_block_page',
  'file' => 'system.admin.inc',
  'file path' => drupal_get_path('module','system'),
);

$items['MyModule/SubMenu/SubMenuItem1'] = array(
  //...
);

我希望SubMenu 会出现在MyModule 菜单的子菜单中,SubMenuItems 会出现在该子菜单下。这是Drupal API 文档中描述的默认行为。

  • 我的模块
    • 菜单项1
    • 子菜单
      • 子菜单项1

但是,所有项目都出现在MyModule 菜单下。

  • 我的模块
    • 菜单项1
    • 子菜单项1
    • 子菜单

我做错了什么?

*编辑:一个错字(我已修复)导致SubMenu 成为一个单独的元素,而不是MyModule 的子元素。不过,我仍然不明白为什么SubMenuItem1 不会在SubMenu 下呈现。

【问题讨论】:

  • 您在哪个 Drupal 版本上?所有这些菜单项会使用相同的回调吗? (菜单处理在 Drupal 6 中有所改变)
  • 我使用的是Drupal 6,菜单项使用不同的回调来显示各种表单。
  • 我在 Drupal 7 上遇到了同样的问题...你知道问题出在哪里了吗?

标签: drupal menu module submenu


【解决方案1】:

我无法重现您的问题 - 使用您的菜单层次结构,所有条目都以预期的顺序和嵌套出现在导航菜单下。

您是否(重新)尝试过从干净的状态(即,您的模块已卸载并且菜单项消失)?为了解释我为什么要问这个,我必须详细说明一下:

Drupal 6 将菜单定义存储拆分为两个表。有menu_router 表,它存储通过hook_menu() 定义的路径 回调关系。 这并没有定义任何“真正的”菜单条目(如菜单菜单,例如导航菜单)。它只定义了 Drupal 内部菜单结构,与显示的菜单无关,但是只有映射路径到回调函数的内部层次结构!

然后是menu_links 表,它存储出现在各种可显示菜单(例如导航、主链接等)下的“真实”菜单条目。那里的条目还通过为每个条目存储一个“父菜单 id”(plid) 来定义嵌套顺序,指向父条目,或 0 表示顶级条目。

现在,每当您通过hook_menu() 定义路径/回调组合时,Drupal 都会将该条目放入menu_router 表中。如果您将它们定义为MENU_NORMAL_ITEMMENU_SUGGESTED_ITEM,Drupal 将另外尝试在menu_links 表中创建一个条目。 如果该路径的条目已经存在,Drupal 将不会改变其在层次结构中的位置,因为它假定用户故意移动它。您应该考虑由 @987654333 创建的 menu_link 条目@ 作为一个方便的附加功能,可以省去通过下面提到的功能显式添加它们的麻烦,但是该机制不是很灵活并且尽量不干扰现有配置(否则手动编辑的菜单会在每次重建时不断重新排序菜单缓存)。

因此,您应该再试一次,同时确保您的所有路径在 `menu_links' 表中都没有现有条目。

为了在安装模块时提供正确的默认菜单(并更好地控制发生的事情),您应该查看menu_link_save()menu_link_maintain() 函数。您可能还想阅读When and how to use menu_links

【讨论】:

  • +1 "如果该路径的条目已经存在,Drupal 将不会改变其在层次结构中的位置,因为它假定用户故意移动了它。"我认为这正是正在发生的事情。重新安装该模块显示它确实创建了所需的默认菜单显示。感谢您提供有用的信息和有用的链接。
【解决方案2】:

hook_menu 并不是真正设置权重的地方,我相信它可以在那里完成,但你会发现只需创建一个普通的菜单项并将其拖动到管理员的菜单对话框中就可以为你节省很多的麻烦和痛苦。

据我了解,原因在于菜单层次结构部分是通过加权系统确定的,而不是由您设置的路径确定的。惯例当然决定了人们如何设置他们的路径,但是仅仅在 admin/monkey 上创建一个普通的菜单项并不会自动将猴子项放入管理菜单中。

【讨论】:

  • 虽然不是绝对必要的,但我想在模块代码中构建模块菜单,以便其他人可以安装它并查看有用的默认菜单层次结构。
  • 这里的文档 [api.drupal.org/api/drupal/includes%21menu.inc/group/menu/7.x] 说应该:The menu system aggregates these items and determines the menu hierarchy from the paths.
猜你喜欢
  • 1970-01-01
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多