我想覆盖显示在用户个人资料上的标签,并将其作为主要链接中的菜单项。
例如,我正在使用Invite模块来定义一些菜单项,包括......
function invite_menu() {
// bunch of menu items...
// User profile tabs
$items['user/%user/invites'] = array(
'title' => 'Invitations',
'page callback' => 'invite_user_overview',
'access callback' => 'invite_user_access',
'access arguments' => array('track invitations', 1),
'type' => MENU_LOCAL_TASK,
'file' => 'invite_admin.inc',
);
}
因为我想覆盖那个MENU_LOCAL_TASK,所以我定义了一个 hook_menu_alter()如下,将项目设置为a 而是主链接中的MENU_NORMAL_ITEM。
function mymod_menu_alter(&$items) {
if (!empty($items['user/%user/invites'])) {
$items['user/%user/invites']['title'] = 'My Override';
$items['user/%user/invites']['type'] = MENU_NORMAL_ITEM;
$items['user/%user/invites']['menu_name'] = 'primary-links';
}
}
到目前为止一切都很好......我重建了menu_router以查看更改,而项目确实如此 不出现在主链接中。
单步执行代码,我发现重建menu_router后,我的新代码 菜单项通过menu_link_save()(menu.inc)运行。我的菜单项进入 此主要链接的功能设置为“menu_name”。但这会被覆盖 以下列方式进入“导航”菜单。
function menu_link_save(&$item) {
// ...
// do some stuff
// ...
// -----------------------------------------------------------
// THIS FAILS
// -----------------------------------------------------------
if (isset($item['plid'])) {
$parent = db_fetch_array(db_query("SELECT * FROM {menu_links} WHERE mlid = %d", $item['plid']));
}
我的项目没有plid。如果确实如此,我们以后会成为金子......
else {
// Find the parent - it must be unique.
$parent_path = $item['link_path'];
$where = "WHERE link_path = '%s'";
// Only links derived from router items should have module == 'system', and
// we want to find the parent even if it's in a different menu.
// -----------------------------------------------------------
// THIS PASSES, SO ...
// -----------------------------------------------------------
if ($item['module'] == 'system') {
$where .= " AND module = '%s'";
$arg2 = 'system';
}
else {
// If not derived from a router item, we respect the specified menu name.
$where .= " AND menu_name = '%s'";
$arg2 = $item['menu_name'];
}
do {
// -----------------------------------------------------------
// WE FIND THE PARENT ("user/%")
// -----------------------------------------------------------
$parent = FALSE;
$parent_path = substr($parent_path, 0, strrpos($parent_path, '/'));
$result = db_query("SELECT COUNT(*) FROM {menu_links} ". $where, $parent_path, $arg2);
// Only valid if we get a unique result.
if (db_result($result) == 1) {
$parent = db_fetch_array(db_query("SELECT * FROM {menu_links} ". $where, $parent_path, $arg2));
}
} while ($parent === FALSE && $parent_path);
}
所以,现在我们有一个父母,它是'user /%',其“menu_name”是“导航”。好的,但这对我想要住在主链接的菜单项来说并不好。接下来会发生的是覆盖......
if ($parent !== FALSE) {
$item['menu_name'] = $parent['menu_name'];
}
我的问题是,我该如何做到这一点?从我可以收集的东西,我需要一个plid,或创建一个plid的东西。这似乎不应该是超级难的。我错过了什么?
答案 0 :(得分:2)
正如你所说:“我需要一个plid,或者创建一个plid的东西” - 所以如果你想让你的项目出现在主链接菜单的顶层,你可以尝试添加一个0的plid( hook_menu_alter
条目中的==无父==顶级条目:
function mymod_menu_alter(&$items) {
if (!empty($items['user/%user/invites'])) {
$items['user/%user/invites']['title'] = 'My Override';
$items['user/%user/invites']['type'] = MENU_NORMAL_ITEM;
$items['user/%user/invites']['menu_name'] = 'primary-links';
$items['user/%user/invites']['plid'] = 0;
}
}
这可能会成功。如果您希望项目显示在主链接菜单的现有项目下,您显然需要获得该现有项目的mlid。
注意/免责声明:明确设置类似的plid没有记录hook_menu()
,并且菜单系统在调用menu_link_save()
之前对items数组进行了一些数据按摩,因此:
因此,您可能希望考虑使用hook_menu_alter
创建所需主要链接条目的替代方法,而是单独使用menu_link_maintain()
(应允许使用通配符路径)。