Visible Description on Drupal Primary Links

Jul 03, 2009

Today I was working on a new site when I realized that the top navigation had descriptions under the links. I asked myself for a few seconds, how can I do that on Drupal? If you don't know what I'm talking about, have a look at this screenshot of another site. digi I'm doing this on a theme, so no need for a module here. What I need to do here is override (the "Drupal way") the theme_links function and that's very easy on a theme, we just need to go to /includes/theme.inc and copy the theme_links() function. Then we can just paste it on our template.php file but we change the function name from theme_links to MYTHEMENAME_links.

I don't want to kill any other part on the site so let's add an extra parameter to the function, in this case $primarylinks = false. By default the function will work like always does but If we pass $primarylinks as TRUE it will add the link description to the link title. Let's see how the function will look like:

function MYTHEMENAME_links($links, $attributes = array('class' => 'links'), $primarylinks = false) {
  global $language;
  $output = '';
  if (count($links) > 0) {
    $output = '<ul '. drupal_attributes($attributes) .'>';
    $num_links = count($links);
    $i = 1;
 
    foreach ($links as $key => $link) {
      $class = $key;
      // Add first, last and active classes to the list of links to help out themers.
      if ($i == 1) {
        $class .= ' first';
      }
      if ($i == $num_links) {
        $class .= ' last';
      }
      if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
          && (empty($link['language']) || $link['language']->language == $language->language)) {
        $class .= ' active';
      }
      $output .= '<li '. drupal_attributes(array('class' => $class)) .'>';
      if (isset($link['href'])) {
        // Pass in $link as $options, they share the same keys.
        if ($primarylinks) {
          $link['html'] = true;
          $output .= l($link['title'] . '<span>' . $link['attributes']['title'] . '</span>', $link['href'], $link);
        } else {
          $output .= l($link['title'], $link['href'], $link);
        }
      }
      else if (!empty($link['title'])) {
        // Some links are actually not links, but we wrap these in <span> for adding title and class attributes
        if (empty($link['html'])) {
          $link['title'] = check_plain($link['title']);
        }
        $span_attributes = '';
        if (isset($link['attributes'])) {
          $span_attributes = drupal_attributes($link['attributes']);
        }
        $output .= '<span '. $span_attributes .'>'. $link['title'] .'</span>';
      }
      $i++;
      $output .= "</span></li>\n";
    }
    $output .= '</front></ul>';
  }
  return $output;
}

If you didn't notice, this is the modified part:

	if ($primarylinks) {
		$link['html'] = true;
		$output .= l($link['title'] . '<span>' . $link['attributes']['title'] . '</span>', $link['href'], $link);
	} else {
		$output .= l($link['title'], $link['href'], $link);
	}

Pretty simple. If you wonder why I added $link['html'] = true, that's because the l() function needs to know it will render on HTML so you dont get the displayed instead of used as HTML. You can do almost anything you want here, the rest is really up to you. This is more like a trick than a tutorial, but I hope you find it useful.

Anonymous's picture
Anonymous on Oct 23, 2009 Hi Nice function! When I add this all my links get a descrition, any tips?
Anonymous's picture
Niels on Nov 15, 2009 This is exactly what i want to get in my Drupal 6 theme i'm making. But i can't seem to get it working. After copy-pasting the code to template.php it just shows the code on top of the homepage. I'm am a drupal beginner but learning on the go... thnx in advance
Anonymous's picture
Trevor Jacobs on Dec 14, 2009 You will need to change a line in the page.tpl.php. I'm using a Zen subtheme, and the original line looked like this: I changed it to this: 'links'), true); ?>
Anonymous's picture
T.J. on Jan 12, 2010 Thanks a ton for the post. I was looking all day how to do this. Works great.

Post new comment

You can use your Gravatar account.

Mollom CAPTCHA (play audio CAPTCHA)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated.