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 ?>: </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...