Insert an image instead of text in a menu item.

description

To insert an image instead of text in a menu item you may rewrite theme_menu_item_link().

Step 1 of 2

Put this code into your template.php inside your themes directory:

<?php
function phptemplate_menu_item_link($item, $link_item) {
   
// Allow HTML if the menu text is an image tag: call l() with 7th argument set to TRUE
    // See <a href="http://api.drupal.org/api/4.7/function/l
" title="http://api.drupal.org/api/4.7/function/l
" rel="nofollow">http://api.drupal.org/api/4.7/function/l
</a>    if( strpos($item['title'], '<img') === 0) {
      return l($item['title'], $link_item['path'], !empty($item['description']) ? array('title' => $item['description']) : array(), NULL, NULL, FALSE, TRUE);
    }
   
  return l($item['title'], $link_item['path'], !empty($item['description']) ? array('title' => $item['description']) : array());
}
?>

Here we just look for the menu title starting with the HTML tag <img and if true call l() with the 7th argument set to TRUE. This will allow HTML inside the menu text. See http://api.drupal.org/api/4.7/function/l.

Step 2 of 2

Now just enter an image tag into the "Title" field inside the "edit menu item" form (administer > menus > (edit or add item)) like <img src="/sites/default/menu_item.gif" />

Notes

  • This code should work in Drupal 5.0 too. At least the l() function did not change from 4.7 to 5.0

what about primary links?

bdornbush - February 16, 2007 - 23:47

This function works for the Navigation menu, but when I try it for a primary link item, I just see the tag as text. I would like to have images instead of text in the primary links menu in the header. Does this require rewriting another function? BTW I am using 5.1.

This seems to work

bdornbush - March 4, 2007 - 00:54

I tried the following with 5.1, and it seems to work fine.

In template.php, istead of rewriting theme_menu_item_link(),
rewrite theme_menu_links() as follows:

<?php
function phptemplate_menu_links($links) {
  if (!
count($links)) {
    return
'';
  }
 
$level_tmp = explode('-', key($links));
 
$level = $level_tmp[0];
 
$output = "<ul class=\"links-$level\">\n";
  foreach (
$links as $index => $link) {
   
$output .= '<li';
    if (
stristr($index, 'active')) {
     
$output .= ' class="active"';
    }
    if (
strpos($link['title'], '<img') === 0) {
     
$output .= ">". l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment'], FALSE, TRUE) ."</li>\n";
    }
    else {
       
$output .= ">". l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']) ."</li>\n";
    }
  }
 
$output .= '</ul>';

  return
$output;
}
?>

Use CSS - background images

field4000 - May 29, 2008 - 01:58

You could use CSS to change the background image of each of the classes.

For example:

.links a:link, .links a:visited
{
display: block;
height: 36px;
}

.links a.menu-1-1-2
{
background: url(../../images/navigation_home.gif) no-repeat;
width: 156px;
}

.links a.menu-1-1-2:hover
{
background: url(../../images/navigation_home_over.gif) no-repeat;
}

.links a.menu-1-2-2-active
{
background: url(../../images/navigation_home_over.gif) no-repeat;
width: 156px;
}

If copying and pasting the top example

optix - July 3, 2008 - 11:57

(which works great by the way, thanks you very much), make sure you double-check the text for wrapping. This should all be on one line:

    // See <a href="http://api.drupal.org/api/4.7/function/l
" title="http://api.drupal.org/api/4.7/function/l
" rel="nofollow">http://api.drupal.org/api/4.7/function/l
</a>

ie
    // See <a href="http://api.drupal.org/api/4.7/function/l" title="http://api.drupal.org/api/4.7/function/l" rel="nofollow">http://api.drupal.org/api/4.7/function/l</a>

Otherwise you will get parse errors.

 
 

Drupal is a registered trademark of Dries Buytaert.