Hi All,

Ok, I have no problems using/creating menus & stuff.

But, for me to be able to modify the design how I need it, it is crucial that I can add some extyra text to the primary links. To be able to achieve perfect rounded tabs, I need to add a <span> tag to the items.

So, the Current menu:

<ul class="links primary-links">
<li class="first menu-1-1-2"><a href="#" title="Main page" class="menu-1-1-2">Home</a></li>
<li class="menu-1-2-2"><a href="#" title="Contact" class="menu-1-2-2">Contact</a></li>
<li class="menu-1-3-2"><a href="#" title="Forum" class="menu-1-3-2">Forum</a></li>
<li class="menu-1-4-2"><a href="#" title="Shop" class="menu-1-4-2">Products</a></li>
<li class="last menu-1-5-2"><a href="#" title="About Us" class="menu-1-5-2">About Us</a></li>
</ul>

Needs to look like:

<div id="topNav">
<ul id="topnavButtons">
<li class="on"><a href="#" title="Main page"><span class="topNavSpan">Home</span></a></li> 
<li class="off"><a href="#" title="Contact"><span class="topNavSpan">Contact</span></a></li> 
<li class="off"><a href="#" title="Forum"><span class="topNavSpan">Forum</span></a></li> 
<li class="off"><a href="#" title="Shop"><span class="topNavSpan">Products</span></a></li> 
<li class="off"><a href="#" title="About Us"><span class="topNavSpan">About Us</span></a></li>   
</ul>			
</div>
</div>

I am scratching my head on this one.

I don't want to make this a custom block, unless I can get the menu to print back that it is "on", or the "current" item.

If anyone could give me a little heads up on this, you would be saving me another hour of frustration.

Thanks in advance for any input.

Regards,
Ryan

[ Edited by: VeryMisunderstood; Added code tags around the span tag ]

Comments

fronbow’s picture

You'll need to do this in the template.php and page.tpl.php files.

This should work as I've got it in my current site's theme.

In your page.tpl.php wherever you display your primary links

<?php if (isset($primary_links)) : ?>
<div class="my-primary-links">
<?php print theme('linksnew', $primary_links, array('class' => 'links primary-links')) ?>
<?php endif; ?>

NB: I'm only doing this for primary links.
Also, I need my links wrapped in a div for some other formatting stuff, but you should be able to take out the my-primary-links div.
You can add more css classes into the class array, eg

<?php print theme('linksnew', $primary_links, array('class' => 'links primary-links some-other-class')) ?>

Then in your template.php file (you may need to create it if you haven't got one already)

/**
 * Override theme_links to include <span> in list.
 */
function phptemplate_linksnew($links, $attributes = array('class' => 'links')) {
  $output = '';
  if (count($links) > 0) {
    $output = '<ul'. drupal_attributes($attributes) .'>';
    $num_links = count($links);
    $i = 1;
    foreach ($links as $key => $link) {
      $class = '';
      // Automatically add a class to each link and also to each LI
      if (isset($link['attributes']) && isset($link['attributes']['class'])) {
        $link['attributes']['class'] .= ' ' . $key;
        $class = $key;
      }
      else {
        $link['attributes']['class'] = $key;
        $class = $key;
      }
      // Add first and last classes to the list of links to help out themers.
      $extra_class = '';
      if ($i == 1) {
        $extra_class .= 'first ';
      }
      if ($i == $num_links) {
        $extra_class .= 'last ';
      }
	  // Add class active to active li 
	  $current = '';
	  if (strstr($class, 'active')) {
	    $current = ' active';
	  }
	  $output .= '<li class="'. $extra_class . $class . $current .'"><span>';
	  // Is the title HTML?
      $html = isset($link['html']) && $link['html'];
      // Initialize fragment and query variables.
      $link['query'] = isset($link['query']) ? $link['query'] : NULL;
      $link['fragment'] = isset($link['fragment']) ? $link['fragment'] : NULL;
      if (isset($link['href'])) {
        $output .= l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html);
      }
      else if ($link['title']) {
        //Some links are actually not links, but we wrap these in <span> for adding title and class attributes
        if (!$html) {
          $link['title'] = check_plain($link['title']);
        }
        $output .= '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
      }
      $i++;
      $output .= "</span></li>\n";
    }
    $output .= '</ul>';
  }
  return $output;
}

I have a feeling this is on a handbook page as well.

HTH

72dpi’s picture

Mate,
I can't thank you enough.

I searched all over the site, but couldn't see this, so thanks for not just passing this one off as a "noob" question.
Sorry to have missed it.

Thanks again mate..... I can't tell you how much time you've just saved me.

*** EDIT ***

Just tested. Awesome, thanks !

Regards,
Ryan

fronbow’s picture

Glad I could help!

_fronbow_

72dpi’s picture

arghghg, actually, this is close, but not quite on it.
To be semantically correct, and to work properly, the code needs to be like:

<li><a href="#"><span>Blah!</span></a></li>

The current output is:

<li><span><a href="#">Blah!</a></span></li>

I have tried to modify my CSS to suit, but not quite right.
Every example of tabbed menu's I use puts spans INSIDE the a href, not outside.

Anyhow, still an awesome hack, will play with it more to see if I can get it to what I need even better.

Cheers again..

fronbow’s picture

For my current site, I'm using the span to display a background img (an arrow) at the side of the text. But I thought it was semantically correct to have the spans outside of the href.

Can I ask why you want the spans outside the href? Have you got an example of a working tab?

Okay, having another go, let me know if this works as it will be untested, (both for html and php)!

<?php
/**
* Override theme_links to include <span> in list.
*/
function phptemplate_linksnew($links, $attributes = array('class' => 'links')) {
  $output = '';
  if (count($links) > 0) {
    $output = '<ul'. drupal_attributes($attributes) .'>';
    $num_links = count($links);
    $i = 1;
    foreach ($links as $key => $link) {
      $class = '';
      // Automatically add a class to each link and also to each LI
      if (isset($link['attributes']) && isset($link['attributes']['class'])) {
        $link['attributes']['class'] .= ' ' . $key;
        $class = $key;
      }
      else {
        $link['attributes']['class'] = $key;
        $class = $key;
      }
      // Add first and last classes to the list of links to help out themers.
      $extra_class = '';
      if ($i == 1) {
        $extra_class .= 'first ';
      }
      if ($i == $num_links) {
        $extra_class .= 'last ';
      }
      // Add class active to active li
      $current = '';
      if (strstr($class, 'active')) {
        $current = ' active';
      }
      $output .= '<li class="'. $extra_class . $class . $current .'"><span>';
      // Is the title HTML?
      $html = isset($link['html']) && $link['html'];
      // Initialize fragment and query variables.
      $link['query'] = isset($link['query']) ? $link['query'] : NULL;
      $link['fragment'] = isset($link['fragment']) ? $link['fragment'] : NULL;
      if (isset($link['href'])) {
        $spanned_title = '<span'. drupal_attributes($link['attributes']) .'>'.$link['title'].'</span>';
        $output .= l($spanned_title, $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, $html);
      } else if ($link['title']) {
        //Some links are actually not links, but we wrap these in <span> for adding title and class attributes
        if (!$html) {
          $link['title'] = check_plain($link['title']);
        }
        $output .= '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
      }
      $i++;
      $output .= "</span></li>\n";
    }
    $output .= '</ul>';
  }
  return $output;
}
?>

All I've done here is changed the link title so that it displays the span around the title text which should make it appear inside the href, let me know whether it does the job!

Cheers

72dpi’s picture

heya mate,

Thanks for that. Did try, but it renders out the link tags like:
<span class="menu-1-1-2">Guestbooks</span> (on the visual)
So, it's breaking the html. tried a few variations, but couldn't get it to render.

I am normally fine with fairly basic php, but this is a lot different to any methods I have used before.

Sorry to waste your time on this one, but by putting the span on the inside of the href, really is the proper way to go, and how every type of rounded tabs menu is written.

I owe you a few beers already, don't I? =)

fronbow’s picture

hmmm, okay, just tested this and my result =

<a href="/resources" class="menu-1-1-2"><span class="menu-1-1-2">resources</span></a>

Here's the new code

<?php
/**
* Override theme_links to include <span> in list.
*/
function phptemplate_linksnew($links, $attributes = array('class' => 'links')) {
  $output = '';
  if (count($links) > 0) {
    $output = '<ul'. drupal_attributes($attributes) .'>';
    $num_links = count($links);
    $i = 1;
    foreach ($links as $key => $link) {
      $class = '';
      // Automatically add a class to each link and also to each LI
      if (isset($link['attributes']) && isset($link['attributes']['class'])) {
        $link['attributes']['class'] .= ' ' . $key;
        $class = $key;
      }
      else {
        $link['attributes']['class'] = $key;
        $class = $key;
      }
      // Add first and last classes to the list of links to help out themers.
      $extra_class = '';
      if ($i == 1) {
        $extra_class .= 'first ';
      }
      if ($i == $num_links) {
        $extra_class .= 'last ';
      }
      // Add class active to active li
      $current = '';
      if (strstr($class, 'active')) {
        $current = ' active';
      }
      $output .= '<li class="'. $extra_class . $class . $current .'"><span>';
      // Is the title HTML?
      $html = isset($link['html']) && $link['html'];
      // Initialize fragment and query variables.
      $link['query'] = isset($link['query']) ? $link['query'] : NULL;
      $link['fragment'] = isset($link['fragment']) ? $link['fragment'] : NULL;
      if (isset($link['href'])) {
        $spanned_title = '<span'. drupal_attributes($link['attributes']) .'>'.$link['title'].'</span>';
// In the line above, you could take out the drupal_attributes var and specify your class
// 
        $output .= l($spanned_title, $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, TRUE);
      } else if ($link['title']) {
        //Some links are actually not links, but we wrap these in <span> for adding title and class attributes
        if (!$html) {
          $link['title'] = check_plain($link['title']);
        }
        $output .= '<span'. drupal_attributes($link['attributes']) .'>'. $link['title'] .'</span>';
      }
      $i++;
      $output .= "</span></li>\n";
    }
    $output .= '</ul>';
  }
  return $output;
}
?>

So, here, I've changed the last var of the l so that it is implicitly set to true because the title is now html.

send the beers over in the afternoon ;)

Let me know whether this nails it?!

72dpi’s picture

Ok, I really do owe you.

Thnaks mate, that truly is fantastic. I am gonna add it to my real design now (works spot on, thanks!).

Oh, had some troubles emailing the beer, would naming my first born child be sufficient? =)

In all seriousness, it's attitudes like yours that make Drupal such a great place to visit & learn.

Thanks again mate..

Ryan

fronbow’s picture

^_^

no problems matey, we're all beginners at some point, and if I can make your drupal experience that little bit better so be it!

Happy drupalling

FranCarstens’s picture

Does anyone know where I can get the D6 solution for this? I have this code in my D5 template file, but it's not working in D6. Any directions would be appreciated.

-- If no-one asked Drupal questions there would be no Drupal answers --