Modify Menu Items in Drupal

Menu Icon

Recently, someone was asking me how to modify the items of a particular menu within a Drupal powered site. In particular, they wanted to modify all but the last menu item. This is where the Drupal API comes to the rescue with its theme_menu_link function. This function allows you to manipulate your menu items as you see fit. Want to add a unique class to a particular menu item? Need to add a string to only certain menu items? Want to replace the menu completely? If you answered yes to any of those, then this is the function for you!

Here's an example adding the mlid's to each menu item for a unique class:

<?php
/**
* Add unique class to all menu items.
*/
function YOURTHEME_menu_link(array $variables) {
 
$element = $variables['element'];
 
$sub_menu = '';

  $element['#attributes']['class'][] = 'menu-' . $element['#original_link']['mlid'];

  if ($element['#below']) {
   
$sub_menu = drupal_render($element['#below']);
  }
 
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return
'<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
?>

Here's an example modifying the text of all but the last menu items:

<?php
/**
* Add a pipe delimiter to all menu items except the last.
*/
function YOURTHEME_menu_link(array $variables) {
 
$element = $variables['element'];
 
$sub_menu = '';

  if(in_array('last',$element['#attributes']['class'])){
  
$element['#title'] = $element['#title'] . ' |';
  }

  if ($element['#below']) {
   
$sub_menu = drupal_render($element['#below']);
  }
 
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return
'<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
?>

That's it! You can use any part of the $element array to customize your menu items (or any PHP or Drupal global variables as well)!

Categories: 
Modify Menu Items in Drupal | Gerrit Brands

Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /homepages/29/d196880538/htdocs/drupal7/includes/common.inc:2681) in drupal_send_headers() (line 1212 of /homepages/29/d196880538/htdocs/drupal7/includes/bootstrap.inc).
  • PDOException: SQLSTATE[42000]: Syntax error or access violation: 1142 INSERT command denied to user 'dbo354826752'@'74.208.16.6' for table 'watchdog': INSERT INTO {watchdog} (uid, type, message, variables, severity, link, location, referer, hostname, timestamp) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9); Array ( [:db_insert_placeholder_0] => 0 [:db_insert_placeholder_1] => cron [:db_insert_placeholder_2] => Attempting to re-run cron while it is already running. [:db_insert_placeholder_3] => a:0:{} [:db_insert_placeholder_4] => 4 [:db_insert_placeholder_5] => [:db_insert_placeholder_6] => http://gerritbrands.com/blog/modify-menu-items-drupal [:db_insert_placeholder_7] => [:db_insert_placeholder_8] => 54.156.92.46 [:db_insert_placeholder_9] => 1503039729 ) in dblog_watchdog() (line 154 of /homepages/29/d196880538/htdocs/drupal7/modules/dblog/dblog.module).

Error

The website encountered an unexpected error. Please try again later.