Creating a dynamic menu link in Drupal

Sometimes you'll need to create a menu link that is different for each user that views it. The simplest way to do this is to create a small custom module that will add the menu link and generate a dynamic URL.

In my case, I wanted a link title 'My Company' that would redirect the user to their own Organic Group.

What to do

  • Create a menu entry

    function grasmash_menu() {
    //create menu item for My Company
    $items = array();

    $items['my-company'] = array(
    'title' => 'My Company',
    'description' => 'View your company\'s page',
    'page callback' => 'grasmash_my_company_link',
    'access callback' => 'grasmash_user_has_company',
    'expanded' => TRUE,
    'weight' => -100,
    'menu_name' => 'primary-links',

    return $items;

    The page and access callbacks are functions that I'm about to create. For more information about the hook_menu function, checkout the hook_menu() entry in Drupal's API. I'd also recommend downloading the Examples for Developers module to get a good sense of how Drupal's basic functions work.

  • Next, create a function that will actually determine the user's company (OG)
    //find user's company. this assume that each user only belongs to one company!
    //for admins, will choose the most recently joined company that user is an admin of
    function grasmash_get_user_company(){
    global $user;
    $nid = db_result(db_query("SELECT og_uid.nid, node.type FROM og_uid, node WHERE og_uid.uid = %d AND node.type = 'company' AND node.nid = og_uid.nid ORDER BY og_uid.created DESC, og_uid.is_admin DESC LIMIT 1", $user->uid));
    return $nid;
  • Let's also create function for the access callback. This will determine whether the user should be able to see the link.
    //does the user actually belong to a company?
    function grasmash_user_has_company(){
    if (grasmash_get_user_company()){
    return TRUE;
  • Lastly, let's redirect the user to the correct node after they click on the link:
    //redirect the user to the right node
    function grasmash_my_company_link(){
    $nid = grasmash_get_user_company();
    drupal_goto('node/' . $nid);
    //return node_view($nid); //you could also simply load the node if you wanted to

And there you have it. Feel free to customize the MySQL query to change which node the user will be redirected to.

A quick note on what we didn't do

We didn't add code that would dynamically change the $items['my-company'] URL. Why? because Drupal only checks on that URL when the menu system needs to be rebuilt. Instead, you need to choose a static URL and write a function that will dynamically load content or redirect the user when that URL is visited.

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.