By Martin Duys


2011-03-31 08:49:26 8 Comments

I have asked exactly this question on Stack Overflow, but it makes more sense to ask it here.

I'm trying to make the text between my tag not display by wrapping it in a and then styling that.

I've added the following function to my template.php file, but I cannot see any difference on the front end; the span just does not appear. (I have cleared my cache.)

Am I using the right function? What am I doing wrong?

function my_theme_link($variables) {
  return '<a href="' . check_plain(url($variables['path'], $variables['options'])) . '"' . drupal_attributes($variables['options']['attributes']) . '><span>' . ($variables['options']['html'] ? $variables['text'] : check_plain($variables['text'])) . '</span></a>';
} 

6 comments

@Hans Rossel 2016-03-12 08:48:49

Most of the cases where you would have needed an extra span before can now be solved with css only:

li {
  position: relative;
  padding-left: 25px;
}

li:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 20px;
  height: 20px;
  background: url('../images/icons.png') no-repeat;
  background-position: 0 0;
}

@Original Scott 2012-03-16 00:54:51

This outputs the same result than the code shown by Taerno, and it works fine in Drupal 7.12.

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

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

  $element['#localized_options']['html'] = TRUE;
  $linktext = '<span class="your_class">' . $element['#title'] . '</span>';

  $output = l($linktext, $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}

You could add in the following code, where "menu_link__menu_block__1" is the name of your menu.

if ($element['#theme']['0'] == 'menu_link__menu_block__1') {

}

I found the name of the menu by printing $element['#theme']['0'] for my menu.

I am trying to add the span to the parent link only, so I will post when I have done that.

@Nebel54 2012-04-27 15:52:16

I think this is the cleaneast solution so far, but two more things: 1. For security reasons you should use check_plain($element['title']) to sanitize the title before echoing it 2. You could use the hook yourtheme_menu_link__menu_block__1 to avoid the if condition

@Taesto 2011-11-29 23:28:15

I found the solution to this problem after a lot of searching. By the way this works to customize the output of the links of any specific menu.

Let me just say first that customizing the primary or main menu links is something essential to any theming, and the only reason I can think of why Drupal programmers made it so hard to do is so that professional Drupal themers can keep their jobs!

I saw solutions using the theme_link function : bad idea because this will alter the output of ALL your links, which will break your site's layout.

So my approach is to you override the theme_menu_link function. I add a condition to use the override only on the specific menu I want. In this example I chose the primary links. To know the name of the menu you want to theme you have to put dsm($variables) and usse the Devel module.

function yourtheme_menu_link(array $variables) {

  $element = $variables['element'];
  $sub_menu = '';

// Replace 'menu_link__menu_block__1' with the name of the menu you want to theme.
if ($element['#theme']['0'] == 'menu_link__menu_block__1') {
  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  }

  $title = $element['#title'];

// I put the span tags in the title.
  $element['#title'] = '<span class="yourclass1"></span><span class="yourclass2">' . $title . '</span><span class="yourclass3"></span>';
// I tell the l() function to keep the HTML tags.
  $element['#localized_options'] += array(
    'attributes' => array(), 
    'html' => TRUE,
  );
  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
// The function renders the links from all the other menus without modification.
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";
}

@kiamlaluno 2011-04-07 10:58:25

Rather than building the anchor tag, and passing the result of url() to check_plain(), you should call l(), which builds the tag for you.
Remember to set $options['html'] to TRUE (where $options is the last parameter passed to l()), when the string you pass as first argument to l() contains HTML tags; by default the function assumes $options['html'] is FALSE.

@WestieUK 2011-03-31 09:01:59

Have a look at http://drupal.org/node/457740 / http://drupal.org/node/988842 and the devel / theme developer module might be useful too.

I think the function your using is for Links in general and is non specific to any menu..

function THEMENAME_links__system_MENUNAME_menu($variables) {
  $output = '';
  foreach ($variables['links'] as $link) {
    $output .= l('<span>'. check_plain($link['title']) .'</span>', $link['href'], $link);
  }
  return $output;
}

EDIT: included span.

@Martin Duys 2011-03-31 09:22:57

Thanks, I sort of follow what you are saying, but I think my issue is that I have to add the <span> tags inside the <a> tag, so that I can make the text in the <a> tag not appeary, but still have the hyperlink. So I need to override the function that actually ouputs the final html snippet.

@WestieUK 2011-03-31 09:24:14

Are you trying to make the text disappear simply for aesthetics, such as using an image button?

@Martin Duys 2011-03-31 09:26:02

yes, that is exactly what I am trying to do.

@WestieUK 2011-03-31 09:29:38

Tried css text-indent:-9999em; ?

@WestieUK 2011-03-31 09:38:30

css-tricks.com/css-image-replacement - good resource for it

@kiamlaluno 2011-03-31 17:21:20

You need also to report to l() that the first parameter contains HTML tags; this is done adding 'html' => TRUE in the array passed as last parameter.

@Martin Duys 2011-04-01 03:31:46

Thanks, kiamlaluno. Mark West solved my problem, but yours is the correct answer to the question that I asked. Would it not be better for you to submit an answer and then I can accept that as the definitive one? Sorry, Mark :-)

@chrisjlee 2011-04-14 15:27:14

@Westie What would you do, if you need to override all menus to provide a <span>?

@thsutton 2011-03-31 08:58:35

You might be interested in the Theme Developer module. It lets you click on elements of a Drupal page to discover which theme function/template generated them, what arguments were passed in, which alternatives are available, etc.

@Martin Duys 2011-03-31 09:10:44

Thanks, I have that installed already. When I click on a menu item I get the following: parent links__system_main_menu and Function called: Them_link() - Hence me trying to override the link function.

Related Questions

Sponsored Content

2 Answered Questions

Print Main Menu inside a block

  • 2015-05-10 00:09:45
  • David Fox
  • 476 View
  • 1 Score
  • 2 Answer
  • Tags:   theming routes

2 Answered Questions

[SOLVED] How can I add a span tag inside my menu link?

  • 2018-08-22 15:25:35
  • Kris Robinson
  • 436 View
  • 2 Score
  • 2 Answer
  • Tags:   8 theming navigation

1 Answered Questions

[SOLVED] Adding a span tag to main menu items

1 Answered Questions

[SOLVED] Main Menu Display Description as span Tag

  • 2013-01-05 18:47:04
  • Alexander
  • 436 View
  • 6 Score
  • 1 Answer
  • Tags:   theming navigation

1 Answered Questions

[SOLVED] how to display sub menu under the respective main menu

  • 2015-02-06 09:39:47
  • Md Eqbal Ahmad
  • 346 View
  • 0 Score
  • 1 Answer
  • Tags:   routes

3 Answered Questions

[SOLVED] How to make the main menu expanded?

  • 2011-07-31 16:50:54
  • Nick.h
  • 13703 View
  • 3 Score
  • 3 Answer
  • Tags:   7 routes theming

2 Answered Questions

[SOLVED] Add element inside main menu block, but outside navigation

1 Answered Questions

1 Answered Questions

[SOLVED] Customize Drupal 6 Nice_Menus Output

  • 2011-06-29 06:27:13
  • Shalan
  • 322 View
  • 0 Score
  • 1 Answer
  • Tags:   routes

0 Answered Questions

Sponsored Content