Insert an image instead of text in a menu item.

Last modified: March 10, 2009 - 22:19

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.

Put the image in the description field ...

ositoblanco - January 26, 2009 - 03:03

drupal-6: Put the image in the description field and exchange title and description later to show the image with the title description.

1: Change the theme_menu_item_link function in template.php to:

<?php
/**
* Implements theme_menu_item_link()
*/
function your-theme-name_menu_item_link($link) {
  if (empty(
$link['localized_options'])) {
   
$link['localized_options'] = array();
  }

  if(
strpos($link['localized_options']['attributes']['title'], '<img') === 0) {
   
// Allow HTML if the menu description is an image tag:
   
$link['localized_options']['html'] = TRUE;
   
// exchange description with title
   
$tmp = $link['localized_options']['attributes']['title'];
   
$link['localized_options']['attributes']['title'] = $link['title'];
   
$link['title'] = $tmp;
  }

  return
l($link['title'], $link['href'], $link['localized_options']);
}
?>

2: Add the image tag to the menu items description:

Enter an image tag into the "Description" field inside the "add/edit menu item" form (administer > menus > (add/edit item))
like

<img src="/sites/your-site.de/files/site/menu_image.gif" />

I'm using Drupal 6 so it was

Mr Cronk - April 20, 2009 - 22:14

I'm using Drupal 6 so it was good to see a solution for this version of Drupal.

I've adapted template.php as you suggest, then added the img tag to the description field. But still, the title text is all I see. How do I "exchange the title and description"? What exactly does that mean?

thanks!

I got this working by adding

tcom - April 24, 2009 - 10:43

I got this working by adding the <img> tag to :
Home › Administer › Site configuration › Input formats › Filtered HTML > Allowed HTML tags

I don't get this either.

Danny_Joris - May 12, 2009 - 22:58

I don't get this either. Adding < img > does not work.

Edit:
Ok it works now, but not with relative paths. Only with absolute paths. Does anyone know why?
I'm happy it works, but as the website is still in development, i will need to move it later, so it will be a bit annoying to change all those paths again.

Plus: i've got another question. Is there a way to change these pictures at onMouseOver or when a certain page is Active? If i can't make this work with drupal easily, that would be a real handicap.

If you don't want to use

ositoblanco - May 16, 2009 - 15:52

If you don't want to use javascript for this purpose the only way I know is to use css. You should give your menu item a class and set a background image for that item.class. For the class:hover you should set another background image.

In the case "when a certain page is Active" you may use the body-class. If your theme don't have this classes you need to add them. Have a look on theme documentation or for example the zen-theme. If you need more help you may ask in the drupal forum or irc.

Hey ositoblanco, thank you

Danny_Joris - May 16, 2009 - 20:13

Hey ositoblanco, thank you very much for the help. In the meanwhile i already found a perfect working sollution for this by asking the at the forum. You can find it here: http://drupal.org/node/460928

I don't get this either

pyctures - May 18, 2009 - 12:33

I added the php code in my "page.tpl.php" for bluemarine theme.
I entered an img tag in the description field for a menu item (<img src="sites/default/files/file.png" />)
I added img tag in the "allowedhtml tags"... I also tested Full HTML option...

But I just see the Menu TITLE.

Do I need to "exchange title and description" ?
How to do this ?

There is also a module for

ositoblanco - May 28, 2009 - 23:10

There is also a module for menu icons at http://drupal.org/project/menu_icons

 
 

Drupal is a registered trademark of Dries Buytaert.