How to add image caption to your imagefield and imagecache

Changes:

09.11.2011 - Fixed error in template.php

Overview

This how to will to point you the right direction, hell even providing you with an solution to how to add caption to your image fields. No magic, no extra modules. We simply take usage of the title field that is a part of imagefield.

What to do

As usual in Drupal are there is multiple ways of doing tings and this is no different. This is two way of solving this in Drupal 6 but rest assure there are others out there.

  1. Use separate tpl.php –file in your theme that override the way the field are normally rendered.
  2. Override the field from within your template.phpk in a preprocess function.
  3. Move the code from option two into your own custom module to remove code from your theme.

Configure filefield, imagefield and imagecache

Skip this section if you already got a working image field. Before we get into the code do we need to configure the basic settings imagefield and imagecache. Install and filefield module, and add an imagefield to one of your content types (node type).

Enable title

Make sure you enable the title tag in your imagefield. I normally also change the title field to a "textarea".

Install imagecache and create a preset that you enable in your newly created imagefield display settings. Verify that it is working as expected before proceeding.

Option 1 - content-field.tpl.php

By now you should have a working imagefield.

  • Copy content-field.tpl.php from the cck –module theme folder and into your theme.
  • I named my field field_image meaning that Drupal will be look for a template file named content-field-field_image.tpl.php so rename your copy of content-field.tpl.php.
  • This file will override how the imagefield is "printed" (rendered) by the theme system. Please remember to flush (rebuild) the theme registry after adding the correctly named file to your theme otherwise will Drupal not detect your new template file.

Imagefield override code added

<?php if (!$field_empty) : ?>
<div class="field field-type-<?php print $field_type_css ?> field-<?php print $field_name_css ?>">
  <?php if ($label_display == 'above') : ?>
    <div class="field-label"><?php print t($label) ?>:&nbsp;</div>
  <?php endif;?>
  <div class="field-items">
    <?php $count = 1;
    foreach (
$items as $delta => $item) :
      if (!
$item['empty']) : ?>

        <div class="field-item <?php print ($count % 2 ? 'odd' : 'even') ?>">
          <?php if ($label_display == 'inline') { ?>
            <div class="field-label-inline<?php print($delta ? '' : '-first')?>">
              <?php print t($label) ?>:&nbsp;</div>
          <?php } ?>
          <?php print $item['view'] ?>
          <?php if ($page == 1): ?>
            <?php if ($item['data']['title']): ?>
              <div class="image-caption"></div>
              <div class="image-caption-text"><?php print $item['data']['title']; ?></div>
            <?php endif; ?>
          <?php endif; ?>
        </div>
      <?php $count++;
      endif;
    endforeach;
?>

  </div>
</div>
<?php endif; ?>

The only changes I did to the original file was adding these lines.

<?php if ($page == 1): ?> // make sure we are not in teaser mode (build mode)
  <?php if ($item['data']['title']): ?> // Make sure that imagefield title actually contain data.
    <div class="image-caption"></div>
    <div class="image-caption-text"><?php print $item['data']['title']; ?></div>
  <?php endif; ?>
<?php endif; ?>

The example above enables this feature to every content type where you reuse this imagefield, so if this is not wanted behavior, and you need to check what content type this is before printing out the image caption.

That is all you need to do. You should be able to see the title text and the background. They are not correctly positioned or event transparent but we are very very close. All we now need is a little CSS love.

Option 2 - template.php - theme_preprocess

Doing this in template.php give Drupal better performance and you you avoid littering your theme with multiple tpl.php –files.

We are overriding the function - theme_preprocess_content_field().

<?php
function theme_preprocess_content_field(&$variables) {
  if (
$variables['field_name'] == 'field_image' & $variables['page']) { // Make sure that the field is present and we are viewing full page view.
   
$element = $variables['element'];
    if(!
$element['items'][0]['#item']['data']['title'] == '') { // Make sure that the title field is not empty.
     
$image_caption = '<div class="image-caption"></div><div class="image-caption-text">' . $element['items'][0]['#item']['data']['title'] . '</div>';
     
$variables['items'][0]['view'] = $element['items'][0]['#children'] . $image_caption;
    }
}
?>

The end result should be the same as the one presented in the first example. This code could also be moved out of template.php and into your own mini-module by using hook_preprocess_content_field().

The CSS code needed

No magic here, but notice how we position the transparent background. For this to work you have to make sure that the field-item you are placing the text on is relative positioned. By doing so are we able to use absolute position the text, relative to the parent object.

.field-field-image .field-item {
  position: relative;
}
.image-caption {
  position: absolute;
  padding: 20px 10px;
  width: 780px;
  bottom: 5px;
  height: 30px;
  background: #000;
  opacity: 0.3;
}
.image-caption-text {
  position: absolute;
  padding: 20px 10px;
  width: 780px;
  bottom: 0;
  color: #eee;
}

Kommentarer

Takk. Får ta meg tid å finskrive del II om bruk av template.php og kansje se hvor forskjellig D7 er når du skal gjøre noe lignende, tross alt er det Drupal 7 dag!

Drupal7 for a solution?

I'm also looking for D7 solution.

Great tutorial. The only issue in Option one is that you need to make sure you also have the content-field.tpl.php overridden in your theme directory as well.