<span> inside anchor tags of Primary Links

phsc - February 13, 2008 - 20:14

Hello everybody

I tried to get <span> tags inside the anchor tags of the primary links. In html I wanted it to look as follows:
<a href="URL"><span>link text</span></a>

Then I had a look at http://api.drupal.org/api/function/theme_links/6 and saw the following paragraph:

if (isset($link['href'])) {
  // Pass in $link as $options, they share the same keys.
  $output .= l($link['title'], $link['href'], $link);
}

I adjusted it to:

if (isset($link['href'])) {
  // Pass in $link as $options, they share the same keys.
  $output .= l('<span>' . $link['title'] . '</span>', $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, TRUE);
}

But all I got is that the <span> tags were printed out as part of the title text instead of interpreted as html code. Does anybody have any idea? Every help would be very appreciated!

Thanks in advance and best regards
phs

modify page.tpl.php

ipwa - February 13, 2008 - 20:20

Although it would be better to do it as a function, you could also go to your page.tpl.php file in the theme you are using, and add the span manually to the primary links.

HTH

Nicolas
-------------------------
http://nic.ipwa.net

Hi ipwa

phsc - February 14, 2008 - 06:36

Hi ipwa

Thanks for your reply, but as you already mentioned I actually want to do it as a function. ;-)

Greetings
phs

using page.tpl.php to add the span

Blue Muse - June 23, 2008 - 20:09

I'm struggling with just adding the span to the page.tpl.php file.

Right now I have:

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

Where do I put the span to be inside the anchor tags? I realize this is a n00bish question. Maybe I'm missing something here?

If this is Drupal 6

AjK - February 13, 2008 - 22:04

If this is Drupal 6 add

<?php
  $links
['html'] = TRUE;
?>

for example:-

<?php
  $links
[] = array(
   
'title' => '<span>'. $title .'</span>',
   
'href' => 'somelocalpath',
   
'html' => TRUE,
   
'attributes' => array(
     
'title' => 'some nice hover alt text',
    ),
  );
  print
theme('links', $links);
?>

Setting the field html to TRUE ensures the title goes through a different filter to check_plain()

The other problem is that your adjustment of l() appears to be the Drupal 5 ways of doing things. If you are using Drupal 5 then don't be looking at the Drupal 6 API.

I will try it

phsc - February 14, 2008 - 06:35

Hi AjK

Thank your for your answer. I will try it after work.
And you are right, my problem appears in Drupal 6, but previously I ran it in Drupal 5 and there it worked.

Best regards
phs

Thanks! It works now!

phsc - February 14, 2008 - 20:19

Hi AjK

This solved my problem! Thanks!

Best regards

working example?

Cocoon - February 19, 2008 - 16:58

Hi phs are you able to paste a working example here, my php is basic and I dont know what to do with the code AJK put through.

Thanks

Hi Cocoon This is the whole

phsc - February 22, 2008 - 20:33

Hi Cocoon

This is the whole function (from the file "template.php") where I had to make changes. Here you can easily see where AJKs code had to be applied.

<?php
function phptemplate_links($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 = $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']) {
       
$class .= ' active';
      }
     
$output .= '<li class="'. $class .'">';

      if (isset(
$link['href'])) {
       
// Pass in $link as $options, they share the same keys.
       
$link['html'] = TRUE;
       
$output .= l('<span>'. $link['title'] .'</span>', $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 .= "</li>\n";
    }

   
$output .= '</ul>';
  }

  return
$output;
}
?>

Best regards
phs

An error here maybe? ....

AjK - March 4, 2008 - 02:19

Phs,

you've made a slight error here I think. In wanting to wrap your links in a span I was expecting the link title to be passed in as html and therefore the caller sets $link['html'] == TRUE in which case it's the callers responsibilty to do output filtering. However, I see you are actually overriding the theme_links() function in your theme layer. So, your code thus:-

<?php
     
if (isset($link['href'])) {
       
// Pass in $link as $options, they share the same keys.
       
$link['html'] = TRUE;
       
$output .= l('<span>'. $link['title'] .'</span>', $link['href'], $link);
      }
?>

really should be done thus:-

<?php
     
if (isset($link['href'])) {
       
// Pass in $link as $options, they share the same keys.
       
$link['html'] = TRUE;
       
$output .= l('<span>'. check_plain($link['title']) .'</span>', $link['href'], $link);
      }
?>

Notice the addition of the check_plain() function around the $link['title'] outside of the additional span html you placed in there?

The reason for that is by calling l() with the html flag true by passes it's internal security step of doing a check_plain() for you.

Why is it needed. Well, if you know the origin of every piece of text that will make a link title then it doesn't matter. But if you have any chance that untrusted user input could leak into a link title, you must close the potential XSS security hole1. And that means making sure untrusted user input is sanitized on output.

Further reading 1

span with no function

adpo - April 22, 2008 - 06:26

Hi,
I need receive something like that:

<div id='navigation-primary'>
<li><span><span><span><span>Booby</span></span></span></span></li>
</div>

How can I insert without calling function:

Could you clean up my code:

<?php print theme('links', $primary_links, ?> '<span>'.'<span>'.'<span>'.'<span>'. <?php array('class' => 'links primary-links') '<span>'.'<span>'.'<span>'.'<span>') ?>
        <?php endif; ?>

Kind ragars,
Adrian

Hi, I have made chandes

adpo - June 13, 2008 - 06:19

Hi, I have made chandes in:
1. page.tpl.php

<?php
<?php if (isset($primary_links)) :
?>

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

<?php
endif;
?>

?>

2. template.php

<?php
function theme_links($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 = $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()))) {
       
$class .= ' active';
      }
     
$output .= '<li class="'. $class .'">';

      if (isset(
$link['href'])) {
       
// Pass in $link as $options, they share the same keys.
       
$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 .= "</li>\n";
    }

   
$output .= '</ul>';
  }

  return
$output;
}
?>

but span tags are missing:

<li class="menu-115 first active">
<a class="active" title="Home Page" href="/stbrigid/node/1">Home Page</a>
</li>

I want receive:

<a class="active" href="/stbrigid/node/1">
<span class="tab">View</span>
</a>

Hi All, Fantastic work. I

nickbits - July 12, 2008 - 12:13

Hi All,

Fantastic work. I am having trouble following some of this though, specifically where the code should be going. I thought I had it, tried it, but nothing. Is there any chance of someone posting sample file(s) for this, that way I can compare excatly what I am doing and where.

Cheers,
Nick
----------------------------------
Nick Young
www.nickbits.co.uk

drupal links with "|"delimiter

jorisx - August 26, 2008 - 13:38

HOw can I change this code to get the "|"delimiter in the primary links

http://api.drupal.org/api/function/theme_links/6
??

in drupal 4.7 it was just one line of code>>

<?php
print theme('links', $primary_links, ' | ')
?>

:-)

Http://www.reloadmedia.com

Thanks So much

black2night - October 19, 2008 - 09:48

Thanks So much

Hi Thanks for this - it's

danmurf - September 18, 2008 - 12:57

Hi

Thanks for this - it's working for me on D6. Although, it's only working for my Primary Links, not any other menu block. Is there any way to make this work on all Drupal menus (Navigation, etc)?

Many thanks
Dan

 
 

Drupal is a registered trademark of Dries Buytaert.