0

I'm using a hook_menu to add some custom menu items to my user menu. One is a link to an external page, one is a duplicate of the "node/add/discussion" page.

I'd expect these menu links to be added to my user menu once and only once. Instead, these links get added to my user menu once for every time I clear cache.

function MYMODULE_menu() {
    $items['external'] = array(
        'title' => 'External',
        'link_path' => 'http://www.example.com',
        'type' => MENU_NORMAL_ITEM,
        'menu_name' => 'user-menu'
    );
    $items['have_a_chat'] = array(
        'title' => 'Have a chat',
        'link_path' => 'node/add/discussion',
        'type' => MENU_NORMAL_ITEM,
        'access_callback' => 'user_is_logged_in',
        'menu_name' => 'user-menu'
    );
    return $items;
}

Exported from the database (SELECT * FROM menu_links WHERE menu_name = 'user-menu';) the menu looks like:

"menu_name","mlid","plid","link_path","router_path","link_title","options","module","hidden","external","has_children","expanded","weight","depth","customized","p1","p2","p3","p4","p5","p6","p7","p8","p9","updated"
"user-menu","2","0","user","user","User account","a:1:{s:5:""alter"";b:1;}","system","0","0","1","0","-10","1","0","2","0","0","0","0","0","0","0","0","0"
"user-menu","10","2","user/register","user/register","Create new account","a:0:{}","system","0","0","0","0","0","2","0","2","10","0","0","0","0","0","0","0","0"
"user-menu","14","0","user/login","user/login","Log in","a:0:{}","system","0","0","0","0","0","1","0","14","0","0","0","0","0","0","0","0","0"
"user-menu","15","0","user/logout","user/logout","Log out","a:0:{}","system","0","0","0","0","10","1","0","15","0","0","0","0","0","0","0","0","0"
"user-menu","20","2","user/password","user/password","Request new password","a:0:{}","system","-1","0","0","0","0","2","0","2","20","0","0","0","0","0","0","0","0"
"user-menu","336","0","profile-main","profile-main",,"a:0:{}","system","0","0","0","0","0","1","0","336","0","0","0","0","0","0","0","0","0"
"user-menu","1071","0","http://www.example.com",,"External","a:0:{}","system","0","1","0","0","0","1","0","1071","0","0","0","0","0","0","0","0","0"
"user-menu","1072","0","node/add/discussion","node/add/discussion","Have a chat","a:0:{}","system","0","0","0","0","0","1","0","1072","0","0","0","0","0","0","0","0","0"
"user-menu","1074","0","http://www.example.com",,"External","a:0:{}","system","0","1","0","0","0","1","0","1074","0","0","0","0","0","0","0","0","0"
"user-menu","1075","0","node/add/discussion","node/add/discussion","Have a chat","a:0:{}","system","0","0","0","0","0","1","0","1075","0","0","0","0","0","0","0","0","0"
"user-menu","1076","0","http://www.example.com",,"External","a:0:{}","system","0","1","0","0","0","1","0","1076","0","0","0","0","0","0","0","0","0"
"user-menu","1077","0","node/add/discussion","node/add/discussion","Have a chat","a:0:{}","system","0","0","0","0","0","1","0","1077","0","0","0","0","0","0","0","0","0"
"user-menu","1078","0","http://www.example.com",,"External","a:0:{}","system","0","1","0","0","0","1","0","1078","0","0","0","0","0","0","0","0","0"
"user-menu","1079","0","node/add/discussion","node/add/discussion","Have a chat","a:0:{}","system","0","0","0","0","0","1","0","1079","0","0","0","0","0","0","0","0","0"

My Drupal version is 7.23.

One odd thing I notice is that "module" is listed as "system" despite the fact that I'm adding these links in a custom module.

How do I fix my code so that these menu links only get added once?

0

This was a problem with link_path as hinted at by @xurshid29 and @ARUN.

link_path "works" in that it inserts a link with the given path into the menu, but it also has the odd side effect of inserting multiple links into the menu - one for each cache clear - despite each link having the same key in $items. It's also undocumented, so I have no idea where I picked it up from.

Removing the link_path argument and replacing it with "page callback" fixes the problem of multiple links being inserted.

"Have a chat" was fixed to explicitly callback the "add discussion form":

$items['have_a_chat'] = array(
    'title' => 'Have a chat',
    'page callback' => 'node_add',
    'page arguments' => array('discussion'),
    'type' => MENU_NORMAL_ITEM,
    'access arguments' => array('create discussion content'),
    'menu_name' => 'user-menu'
);

And "external" was fixed to page callback a function that then calls drupal_goto.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.