theme_menu_link

7 menu.inc theme_menu_link(array $variables)
8 menu.inc theme_menu_link(array $variables)

Returns HTML for a menu link and submenu.

Parameters

$variables: An associative array containing:

  • element: Structured array data for a menu link.

Related topics

File

includes/menu.inc, line 1621
API for the Drupal menu system.

Code

function theme_menu_link(array $variables) {
  $element = $variables['element'];
  $sub_menu = '';

  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";
}

Comments

Add unique class (mlid) to all menu items.

I needed to style a few random menu links. Main and secondary menus has a great class .menu-123 (.menu-mlid) to do that. So here how you can port the same behavior to any/all menu items:

<?php
/**
* Add unique class (mlid) to all menu items.
*/
function superseven_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";
}
?>

Wouldn't this be more concise and flexible?

Or is this the wrong way to do it?

<?php
function superseven_menu_link(array $variables) {
 
$variables['element']['#attributes']['class'][] = 'menu-' . $variables['element']['#original_link']['mlid'];

  return
theme_menu_link($variables);
}
?>

Also with menu title as class

<?php
/**
* Add unique class (mlid) to all menu items.
* with Menu title as class
*/

function yourtheme_menu_link(array $variables) {
 
$element = $variables['element'];
 
$sub_menu = '';
 
$name_id = strtolower(strip_tags($element['#title']));
// remove colons and anything past colons
 
if (strpos($name_id, ':')) $name_id = substr ($name_id, 0, strpos($name_id, ':'));
//Preserve alphanumerics, everything else goes away
 
$pattern = '/[^a-z]+/ ';
 
$name_id = preg_replace($pattern, '', $name_id);
 
$element['#attributes']['class'][] = 'menu-' . $element['#original_link']['mlid'] . ' '.$name_id;
  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";
}
?>

Thank you

Hey thanks it works great!

Definition of $element

Do you know where I can get the $element array definition?

Thanks!

adding level deph as class

<?php
function [your_theme]_menu_link(array $variables) {
 
$element = $variables['element'];
 
$sub_menu = '';
 
 
$element['#attributes']['class'][] = 'level-' . $element['#original_link']['depth'];

  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";
}
?>

so that's how!

I've spent half a day trying to get the depth when I've stumbled across your example with $element['#original_link']['depth']. Thanks, that solved a huge problem on my part!

How to add class to the menu himself

I wanna add class to the whole menu: not to the "il", but to "ul".
How to do its?

theme_menu_tree

Use theme_links() to add class to <ul>

tazir1: @see attributes at theme_links()

Theme only a specific menu block.

This gave me some trouble so I thought I'd share.

We needed to style only a specific menu block (top nav) but not the sidebar nav that was generated off of the same menu.

So theme_menu_link__main_menu() did not work for us.

However, I was able to target only the block I needed using the menu block module and theme_menu_link__menu_block__[block-number]()
described under "Theme Menu functions".

Hopefully this helps some one else as well.

Print out variables

I found this helpful when customizing the link info.

<?php
//print out variables for the link array
function theme_menu_link(array $variables) {
  return
print_r($variables['element']);
}
?>

Targeted Override

I don't see it documented elsewhere that you can implement a THEMENAME_menu_link__MENU_NAME() function as an override for a specific menu.

See http://drupal.org/node/254940#theme-suggestions-for-menus.

Just add the menu name and your theme name

wgsimon, to target specific menu, use the name of the menu from admin/structure/menu page (replace any hyphens with underscores) and append your theme name to the beginning of the function.

Make any menu specific changes to the body of the function and you are done!

Login or register to post comments