Drupal programmatically adding an item to a menu

12,352

Solution 1

The menu system is cached, so you can't add or remove menu items as you please based on user, page viewed, custom logic etc. That is you can't do it without having to clear the menu cache which would cause a severe performance hit.

What you could do, to create this effect is to create some custom logic to define the access control on the menu item. Since Drupal hides menu items that users doesn't have access to, you could under certain circumstances deny permission to hide the menu item. This is a bit hackish solution.

Another solution which I would prefer, would be to use js or css to hide or show the menu. You could dynamically add/remove a class on the body to determine if the menu item should be shown or not. This would quickly become unmanagable if you need several of these kind of menu items, however.

Solution 2

You need to implement hook_menu in your module. Example:

<?php
function mymodule_menu() {
  $items['mymodule/links'] = array(
    'title' => 'Links', 
    'page callback' => 'mymodule_links_page', 
    'access arguments' => array('access content'), 
    'type' => MENU_SUGGESTED_ITEM,
  );
  return $items;
}
?>

The 'type' => MENU_SUGGESTED_ITEM, part makes it optional, so it can be enabled by the end user - is that what you meant with "conditionally"? If not, please explain what kind of "conditionally" you're looking for.

Solution 3

Or you can use the 'type' => MENU_NORMAL_ITEM, since it is enabled by default, but can be disabled any time. This of course depends on your preferences. See http://api.drupal.org/api/drupal/includes--menu.inc/group/menu/7 for further reference.

Another good thing to know when using module defined menu items in custom menus might be how to programmatically create the menu you want to use so that everything is created "out of the box". Simply add a mymodule.install-file where you put the following code:

<?php  
function mymodule_install() {  
  $menu = array(  
    'menu_name' => 'links',  
    'title' => 'My Custom Links',  
    'description' => 'Descriptive text.',  
  );  
  menu_save($menu);  
}  
?>

If you have an uninstall function, don't forget to not only deactivate the module, but also to uninstall it. Reenable the module, flush your caches and the menu item should be there!

Solution 4

You can dynamically show or hide a menu item based on a condition ( access callback ).

Here is an example from https://drupal.org/project/examples:

<?php
function mymodule_menu() {
  $items = array();

  $items['my-menu-item'] = array(
    'title' => 'My Menu',
    'description' => 'My description',
    'page callback' => 'my_page_link_callback_function_name',
    'access callback' => 'can_the_user_see_this_item',
    'expanded' => TRUE,
    'weight' => -100,
    'menu_name' => 'primary-links',
  ); 

  return $items;
}

// Here we determine if the user can or can not see the item.
function can_the_user_see_this_item(){
  if (MY_CONDITION){
    return TRUE;
  }
  else {
    return FALSE;
  }
}

Solution 5

Use menu_link_save() function

Saves a menu link.

After calling this function, rebuild the menu cache using menu_cache_clear_all().

Parameters

$item: An associative array representing a menu link item, with elements:

link_path: (required) The path of the menu item, which should be normalized first by calling drupal_get_normal_path() on it.
link_title: (required) Title to appear in menu for the link.
menu_name: (optional) The machine name of the menu for the link. Defaults to 'navigation'.
weight: (optional) Integer to determine position in menu. Default is 0.
expanded: (optional) Boolean that determines if the item is expanded.
options: (optional) An array of options, see l() for more.
mlid: (optional) Menu link identifier, the primary integer key for each menu link. Can be set to an existing value, or to 0 or NULL to insert a new link.
plid: (optional) The mlid of the parent.
router_path: (optional) The path of the relevant router item.
$existing_item: Optional, the current record from the {menu_links} table as an array.

$parent_candidates: Optional array of menu links keyed by mlid. Used by _menu_navigation_links_rebuild() only.

Return value

The mlid of the saved menu link, or FALSE if the menu link could not be saved.
Share:
12,352
Sally
Author by

Sally

Updated on June 04, 2022

Comments

  • Sally
    Sally almost 2 years

    I wish to conditionally add an item to a menu. I have a custom module and a menu called "links". How would I add an item to a menu in my module code?