Designed to
delight
we design & develop
exceptional Drupal websites
The Beatles
 
Designed to
inform
we design & develop
exceptional Drupal websites
 
Designed to
unite
we design & develop
exceptional Drupal websites
SGI UK
 
Designed to
inform
we design & develop
exceptional Drupal websites
 
Designed to
delight
we design & develop
exceptional Drupal websites
 
Designed to
entice
we design & develop
exceptional Drupal websites
 
Designed to
engage
we design & develop
exceptional Drupal websites
 
Designed to
convert
we design & develop
exceptional Drupal websites
 
Designed to
motivate
we design & develop
exceptional Drupal websites
 
Designed to
delight
we design & develop
exceptional Drupal websites
 
Designed to
influence
we design & develop
exceptional Drupal websites
 
Designed to
delight
we design & develop
exceptional Drupal websites
 
Designed to
inform
we design & develop
exceptional Drupal websites
 
Designed to
convert
we design & develop
exceptional Drupal websites
Clovis Canopies
 
Designed to
network
we design & develop
exceptional Drupal websites
 
Designed to
motivate
we design & develop
exceptional Drupal websites
 

Passing on attributes from render arrays to image theme functions

Today I needed to apply a CSS class and a "usemap" attribute to an imagefield in Drupal. So I created my MY-FIELD-IDENTIFIER.tpl.php file (based upon field.tpl.php) and made a couple of minor changes: -

<div class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>
  <?php if (!$label_hidden) : ?>
    <div class="field-label"<?php print $title_attributes; ?>><?php print $label ?>:&nbsp;</div>
  <?php endif; ?>
  <div class="field-items"<?php print $content_attributes; ?>>
    <?php foreach ($items as $delta => $item) : ?>
      <?php
       
// Add the image map and class attributes
       
$item['#item']['attributes']['usemap']="#uk_map";
       
$item['#item']['attributes']['class']="image-map";
     
?>

      <div class="field-item <?php print $delta % 2 ? 'odd' : 'even'; ?>"<?php print $item_attributes[$delta]; ?>><?php print render($item); ?></div>
      <map id="_uk_map" name="uk_map">
          .....
      </map>
    <?php endforeach; ?>
  </div>
</div>

Ah, that was easy, I think. Sadly not... When the HTML was rendered there were no classes and no usemap attributes applied to the image.

Digging into the documentation on Drupal.org and stepping through the code I discovered that attributes are not passed from render arrays to theme functions. I've proposed a fix here - http://drupal.org/node/1451820.

In the mean time it's possible to override the theme function and make it pass on attributes to the theme image functions (don't change the core code).

Here's the snippet: -

<?php
// Override theme_image_formatter
function THEMENAME_image_formatter($variables) {
 
$item = $variables['item'];
 
$image = array(
   
'path' => $item['uri'],
   
'alt' => $item['alt'],
  );

  if (isset(
$item['width']) && isset($item['height'])) {
   
$image['width'] = $item['width'];
   
$image['height'] = $item['height'];
  }

 
// Do not output an empty 'title' attribute.
 
if (drupal_strlen($item['title']) > 0) {
   
$image['title'] = $item['title'];
  }
 
 
// HERE'S THE EXTRA CODE
  // Pass on any attributes
 
if(isset($item['attributes'])) {
   
$image['attributes'] = $item['attributes'];
  }

  if (
$variables['image_style']) {
   
$image['style_name'] = $variables['image_style'];
   
$output = theme('image_style', $image);
  }
  else {
   
$output = theme('image', $image);
  }

  if (!empty(
$variables['path']['path'])) {
   
$path = $variables['path']['path'];
   
$options = $variables['path']['options'];
   
// When displaying an image inside a link, the html option must be TRUE.
   
$options['html'] = TRUE;
   
$output = l($output, $path, $options);
  }

  return
$output;
}
?>

Just add this to your template.php file...