Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drupal Override Custom Menu Template

Tags:

html

drupal

I created a custom menu called "sub-top-nav" and now I'd like to override the html output. In particular I would like to add an unique class to each item like.

This is how it looks atm:

<div class="clear-block block block-menu" id="block-menu-menu-sub-top-nav">
    <div class="content">
    <ul class="menu">
      <li class="leaf first"><a title="Test 1" href="/test1">Test 1</a></li>
      <li class="leaf"><a title="Test 2" href="/test2">Test 2</a></li>
      <li class="leaf active-trail"><a class="active" title="Test 3" href="/test3">Test 3</a></li>
      <li class="leaf last"><a title="Test 4" href="/test4">Test 4</a></li>
    </ul>
  </div>
</div>

And I'd like to change it into:

<div class="clear-block block block-menu" id="block-menu-menu-sub-top-nav">
  <div class="content">
    <ul class="menu">
      <li class="leaf test1 first"><a title="Test 1" href="/test1">Test 1</a></li>
      <li class="leaf test2"><a title="Test 2" href="/test2">Test 2</a></li>
      <li class="leaf test3 active-trail"><a class="active" title="Test 3" href="/test3">Test 3</a></li>
      <li class="leaf test4 last"><a title="Test 4" href="/test4">Test 4</a></li>
    </ul>
  </div>
</div>

This would give me more styling power. Any idea how that works?

Thanks in advance!

like image 299
n00b Avatar asked Feb 23 '10 10:02

n00b


4 Answers

Drupal 7 uses theme_menu_link instead of theme_menu_item

<?php
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";
}
?>
like image 137
Fedir RYKHTIK Avatar answered Oct 25 '22 11:10

Fedir RYKHTIK


I got it to work now. This piece of code might help someone else as well! It goes into yourtheme/template.php

function phptemplate_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {

  $class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));

  if (!empty($extra_class))
    $class .= ' '. $extra_class;

  if ($in_active_trail)
    $class .= ' active-trail';

  $class .= ' ' . preg_replace('/[^a-zA-Z0-9]/', '', strtolower(strip_tags($link)));

  return '<li class="'. $class .'">'. $link . $menu ."</li>\n";
}
like image 34
n00b Avatar answered Oct 25 '22 11:10

n00b


After looking through the API I finally found an easy solution to tag the root menu with the same class (this is useful to style only the top level menus uniquely, while maintaining them dynamically friendly). Simply use the plid instead of mlid. I noticed the plid is always 0 for top level menus.

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

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

  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }

  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
        $count = 1;
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
like image 24
Alan V. Avatar answered Oct 25 '22 11:10

Alan V.


You can use the theme_menu_item function in your theme's template.php to do pretty much whatever you want to those menu items, including adding classes, ID's, etc.

like image 23
Mike Crittenden Avatar answered Oct 25 '22 12:10

Mike Crittenden