Menu pain

Photo of Greg Harvey
Thu, 2008-01-10 22:20By greg

One of the most painful experiences you are likely to have with Drupal 5.x, or earlier, is altering the menus served up by the core User module. Thankfully, Drupal 6 permits editing the User module menu items (or so I'm assured) and also has the seemingly useful hook_menu_alter, which I guess works in a similar fashion to hook_form_alter but, predictably, for menus. (I haven't verified this.)

I have a current client who wants to have a variety of edit options for Nodeprofile fields and User settings, as well as bespoke names on the menu items exposed by the User module.

I've tried everything, and I have to say the solution is UGLY, but it works. I ended up following this article having exhausted all other avenues. You can see my comment at the bottom of the page there, making things a little more controllable. It's not ideal, but at the moment in Drupal 5.x you have little choice when this use case smashes in to you, presuming your client won't be dissuaded.

In the end my code looked like this. It's well commented, so you should be able to follow it and what I'm attempting to achieve:

//this block contains bespoke code for account editing
//and then uses module_invoke to load the My WhatTalent
//menu via the menu module:

global $user;

//make sure custom menu is blank to start with
$thismenu = "";

//if user is logged in, set up and
//build path vars and menu
if ($user->uid != '') {

//load various profile nodes to get nid for dynamic edit menu items
$user_path = "user/".$user->name;
$edit_account_path = "user/".$user->uid."/edit";
$basicinfo_node = node_load(array('uid' => $user->uid, 'type' => 'profile_basic'));
$aboutme_node = node_load(array('uid' => $user->uid, 'type' => 'profile_about_me'));
$usernode = node_load(array('uid' => $user->uid, 'type' => 'usernode'));
$links_node = node_load(array('uid' => $user->uid, 'type' => 'profile_links'));

$basicinfo_menu_path = "node/".$basicinfo_node->nid."/edit";
$nodeimages_menu_path = "node/".$usernode->nid."/images";

//usernode and basic info must exist, but about me and links may not
//so we need to handle this
if ($aboutme_node->nid != '') {
$aboutme_menu_path = "node/".$aboutme_node->nid."/edit";
} else {
$aboutme_menu_path = "node/add/profile-about-me";
}

if ($links_node->nid != '') {
$links_menu_path = "node/".$links_node->nid."/edit";
} else {
$links_menu_path = "node/add/profile-links";
}

$thismenu = '

  • '.l('Edit my account', $edit_account_path, array('title' => 'Edit my account')).'
  • '.
    '

  • '.l('My profile', $user_path, array('title' => 'My profile')).
    '

    '.
    '

  • ';

    }

    print '

    ';

    ?>

    Nasty, but effective, and as far as I know this is the only way to play with the User module and other dynamic menus.

    Just as an aside, there are many other cool things Drupal 6 is doing which I will doubtless touch on over the months. I am yet to delve in to it properly, as the module support just isn't there just yet, but from the look of the documentation, it's a marked improvement.