Main content begins here

Add Image to Menu Items in Drupal 7 (D7)

Thursday, November 15, 2012

I needed to add images to a Drupal 7 menu. In my case, the menu items are pages in the site that I've added to the menu during content creation, via the Menu Settings. I wanted the menu images to be under control of the CMS (not some CSS trick) so I added a field to the Page content type to allow for an image upload I called Navigation Image.

The images are uploaded in color. Inactive menu items show black/white versions of the color image, meaning most images would be black/white most of the time. Here's how I did it.

First, make sure you've added the image upload and have uploaded a few test images. Install and enable ImageCache Actions for D7 so we can make black & white versions on the fly. Go to Configuration > Media > Image styles. Create a preset and use Desaturate to get a black and white version of whatever color image is uploaded.

In the template.php file we're going to override theme_menu_link(). Apologies, I am primarily front end so my code will not be succinct.

function THEMENAME_menu_link(array $variables) {
   
    // declare variables or suffer annoying warnings
    $element = $variables['element'];
    $image = '';
    $img_path = '';
 
    // if this menu item exists in a particular block
    if (in_array("menu_link__menu_block__2", (array) $element['#theme'])):
       
        // turn path into node id for this menu item
        $mnid = substr( $element['#original_link']['link_path'], 5 );
       
        // find original image path for this node
        $fid = db_query('SELECT field_img_nav_fid FROM {field_data_field_img_nav} WHERE entity_id = :fid', array(':fid'=>$mnid))->fetchField();
        $uri = db_query('SELECT uri FROM {file_managed} WHERE fid = :fid', array(':fid'=>$fid))->fetchField();
     
        // if item is NOT active use the B&W version
        if (!in_array("active-trail", (array) $element['#attributes']['class'])):
            $img_path = image_style_url('black-white', $uri);
       
        // if item is active use color version
        else:
            $img_path = str_replace('public:/', variable_get('file_public_path', '/sites/default/files'), $uri);
        endif;
     
        // if we have some path insert it in image tag
        if($img_path):
            $image = '<span class="nav_image"><a href="'.url($element['#original_link']['link_path']).'"><img src="'.$img_path.'" alt="'.$element['#title'].'" /></a></span>';
        endif;
    endif;
 
    $sub_menu = '';

    if ($element['#below']) {
        $sub_menu = drupal_render($element['#below']);
    }
    $output = l($element['#title'], $element['#href'], $element['#localized_options']);
   
    // if we had an image to work with, add span around original content for styling
    if($img_path): $output = '<span class="link_stuff">'.$output.'</span>'; endif;
   
    // add $image in front of other content so it will show as image above text
    return '<li' . drupal_attributes($element['#attributes']) . '>' . $image . $output . $sub_menu . "</li>\n";
}

Post new comment

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <p> <h2> <br> <img>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.

That is exactly what I'm looking for! I think you're a mind reader... everything looks awesome. Thanks for your hard work.

E. H., Owner TheHarb.com
Copyright ©2001-2017 Way Cool Web Design LLC. All Rights Reserved.