3

在为模块实现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

4

2 回答 2

6

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

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

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

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

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

所以你应该再试一次,同时确保你的路径在“menu_links”表中没有现有的条目。

为了在安装模块时提供适当的默认菜单(以及更好地控制发生的事情),您应该查看menu_link_save()menu_link_maintain()功能。您可能还想阅读何时以及如何使用 menu_links

于 2009-12-08T20:03:24.867 回答
0

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

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

于 2009-12-04T01:16:18.503 回答