Visible Description on Drupal Primary Links

Jul 03, 2009
by Ivan

UPDATE: This article applies to Drupal 6.

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.

Posted in