Node Image Gallery with ImageField

ExampleWhen image-sets are discussed it's usually in the context of a full featured photo gallery, but there's another common use: including a set of images with the content of a node. For example, product images with a product node or a "mini" photo album with an article. The CCK ImageField combined with a jQuery module like Thickbox makes adding image-sets to nodes easy. Here's how.

Overview

This "recipe" describes how to add a gallery style photo-set to a node. This photo-set stands apart from the node content as a set of thumbnails which can be clicked on to display the full-size version. The Thickbox slide-show feature is also implemented so viewers are able to step through the full-size version of the pictures without exiting the viewer. Although Thickbox is used, this technique should be easily adoptable to different plug-ins.

An example of the technique can be seen here: Finding the Blue Whale

We create the gallery by adding a CCK ImageField to the target node and theming it. That's it. Thanks to ImageCache, ImageField, and Thickbox module integration, the rest is configuration.

The following modules are required:

The steps are:

  1. Create ImageCache preset for a thumbnail picture
  2. Add a CCK ImageField to the target node type to hold the photo-set
  3. Theme the ImageField

Before you start, decide:

  • Maximum size for picture
  • Thumbnail size

Other Notes:

  • This technique works well for a relatively small amount of pictures. The Edit Node user interface for Image Field becomes unruly for picture management when you add a lot of images.
  • The file used to theme the gallery image field is an almost line-for-line copy of the Views Grid View theming file, which creates a HTML table with one picture per cell. If you want different theming you should have enough information to implement it after reading this article.
  • In order for CCK theming to work, you need to have a copy of content-field.tpl.php in the theme directory.
  • Thickbox displays the image title field with the large version of the image. Though technically a title, it can also be used more like a caption. It's simply a matter of length.

Detailed Set Up

For the purposes of this demo I've created a content type called "article". The mini-gallery can be attached to any node type, and even multiple node types. Images sizes are set so a full sized picture can be no larger than 1024x768 pixels. The thumbnails are scaled to 200 pixels wide.

Modules

Install, enable, and configure the following modules:

  • CCK
  • FileField
  • ImageField
  • ImageCache
  • ImageAPI + ImageAPI GD2 or ImageAPI ImageMagick
  • Thickbox

Image Cache Preset

Create the Image Cache preset for the module:

  1. Go to Home > Administer > Site building > ImageCache
  2. Add new preset: thumb200w
  3. Add Scale: Width: 200 to the preset
    Image Cache Preset

Image Field

Adding a "mini-gallery" image field to the node:

  1. Go to Home > Administer > Content management > Content Types
  2. Go to Manage Fields for Article (or your target node type)
  3. Add an ImageField named Mini Gallery
    Mini Gallery
  4. Mini-Gallery Image Field settings:
    Maximum resolution for Images: 1024x768
    Title text settings: Enable custom title text
    Number of values: Unlimited
  5. Go to Display Fields tab
  6. Under the Basic settings for field Mini Gallery:
    Label: Hidden
    Teaser: Check Excluded checkbox
    Full node: Select Thickbox: thumb200w image
    Basic Field Display
  7. Under RSS settings for field Mini Gallery:
    thumb200w image linked to image
  8. If you are using Content permission, set the user permissions for the new content field.

Theme the Image Field

To theme the image field to appear as shown in the example:

  1. Copy content-field.tpl.php from sites/all/modules/cck/theme to your theme directory. A quirk in CCK field theming requires this file to exist in your theme directory before any other CCK theme files are recognized.
  2. Create a file named content-field-field_mini_gallery.tpl.php
  3. Add the following code:
    <?php
    // $Id:$

    /**
    * @file content-field-field_mini-gallery.tpl.php
    * Theme implementation to display multiple values in the mini-gallery field.
    *
    * Available variables:
    * - $node: The node object.
    * - $field: The field array.
    * - $items: An array of values for each item in the field array.
    * - $teaser: Whether this is displayed as a teaser.
    * - $page: Whether this is displayed as a page.
    * - $field_name: The field name.
    * - $field_type: The field type.
    * - $field_name_css: The css-compatible field name.
    * - $field_type_css: The css-compatible field type.
    * - $label: The item label.
    * - $label_display: Position of label display, inline, above, or hidden.
    * - $field_empty: Whether the field has any valid value.
    *
    * Each $item in $items contains:
    * - 'view' - the themed view for that item
    *
    * @see template_preprocess_content_field()
    */
     
    $columns = 4;
     
    $rows = array_chunk($items, $columns);
    ?>

    <?php if (!$field_empty) : ?>
    <table class="mini-gallery">
      <tbody>
        <?php foreach ($rows as $row_number => $columns): ?>
          <?php
            $row_class
    = 'row-' . ($row_number + 1);
            if (
    $row_number == 0) {
             
    $row_class .= ' row-first';
            }
            if (
    count($rows) == ($row_number + 1)) {
             
    $row_class .= ' row-last';
            }
         
    ?>

          <tr class="<?php print $row_class; ?>">
            <?php foreach ($columns as $column_number => $item): ?>
              <td class="<?php print 'col-'. ($column_number + 1); ?>">
                <div class="photo-image"><?php print $item['view']; ?></div>
                <div class="photo-title"><?php print $item['data']['title']; ?><div>
              </td>
            <?php endforeach; ?>
          </tr>
        <?php endforeach; ?>
      </tbody>
    </table>
    <?php endif; ?>

    The code is also available in a downloadable file. Drupal mungs the name, so you'll need to remove some underscores if you use it directly.
  4. Refresh the cache so Drupal sees the change.
  5. Depending on how your theme displays tables, you may need some addition CSS to complete the formatting.

Notes:

  • If you turn on the CCK ImageField description or alt attributes, they can be accessed in the theme file in the $item['data'] variable.
  • This theming applies to any instance of the mini-gallery field on any node. In other words, by theming the CCK field, you don't have to theme the images in any node template files.

Comments

Hi Dale,

Thanks for sharing this recipe.

I have taken a slightly different route while creating similar functionality by using the gallery_assist module http://drupal.org/project/gallery_assist. I can also associate an existing node type with this gallery functionality. Here is a live example http://stanislausbandra.in/stanschool/

Gerry

Thank you for that information Gerry, I didn't even check to see if there was a module. I would have still gone the theming route, if only to have fewer modules to maintain, but I think a module will be a better option for people not as comfortable with theming.

I also created the same type of gallery with the Views Attach module. It had the advantage of being easy to put in code as a default view or using the Features module. In the end, it seemed overkill to call a View when I could simply theme the field.

Given the variety of methods to do this it may have been better to classify this as an example of how to theme a CCK field!

with a similar result is the brilliant gallery. It can mess with formatting sometimes but for the most part, it's a good way to get a little mini-gallery into a node...

brilliant gallery

I've used this method quite a lot in the past, it's really nice and easy to set up, unless you already have some kind of image gallery feature that you can use in different installations.

I do have to nag at your template file though ;) There's no need to use a table, just the divs combined with some CSS are fine. Advantages: less markup and stops people who nag at you, saying tables are for tabular data :)

Anja, this is something I thought about. The issue is we don't know the width of the image ahead of time and the text needs to wrap at the same width as the image. If a flag-ship module like Views with the many people smarter than me working on it uses a table in this circumstance, I will gladly follow.

If you have sample code or a URL to sample code that works under these circumstances, please post. I couldn't find or create any that worked without explicitly setting element width. But I'm not a CSS guru.

There's also an argument to be made that the images are tabular data, in as much as they comprise a information set. In other words, this isn't a arrangement of different elements on a grid, this is a collection of related information (pictorial) presented together to show a set of facts. Having said that, I would have used div blocks if I could have found a general purpose solution.

I figured you do know the image width since your using imagecache and all the images in the example have the same width. This is how I solve this problem - I know the size of the image, so I can give the div a width.

If you don't know the width or height then I guess you are right about using tables because that tends to look much cleaner in such a case.

http://drupal.org/project/galleryformatter

I recently created this module, please do give it a try, it's a clean and quick solution, getting you a nice looking jquery gallery in 2 minutes.

Manuel, the approach of using a CCK formatter makes a lot of sense to me. Would definitely consider this module for a future gallery project. Whether I actually used it or not would depend on whether there was a gallery style that met my requirement, or was close enough that theming it was less work than simply theming the field directly. It would be nice if the project page listed the gallery styles.

Hey, I the theme I put in isn't displaying a table at all and it also isn't displaying the title below the images. I tried putting the two php files in site/all/themes and also in ./themes and neither worked. I've also refreshed the cache from Site Information. Am I missing something? Thanks.

I fail, just had to put in in the directory of my active theme of course..

Works great though, better than those modules that were posted to be honest. Also, using Lightbox instead of Thickbox.

I made small galleries for one content type and it works quite satisfactory. Had to double check the field template thougn as I had copied the title from the first line of the code. This resulted in a dash in the filename instead of underscore (mini-gallery.tpl and not the correct mini_gallery.tpl).

Also tried working with divs but this proved complicated because of the floating of other content after the gallery.

what is another way to switch between 3-4 thumbnails and corresponding big image? Like this examples:

http://www.amazon.com/gp/product/images/B000SKXHCU/ref=dp_images_0
http://www.live-inspired.com/She-by-Kobi-Yamada-P53
http://www.cargoh.com/product/blue-birds-coin-purse

I want make it without any use of jQuery library and Thickbox: as I always try to avoid Thickbox/Lightbox/Fancybox and other similar javascript plugins whenever it's possible, as its all very slow to load, plus black background break page design. How to make this switcher only with Javscript/CSS?

I was looking for a mini image gallery inside a node. The method you describe is more like a popup or overlay type gallery and can be achieved with all the "box" type modules e.g. lightbox, colorbox, thickbox etc etc. How about a real mini gallery actually embedded inside the node/page without any popup type action. Some real estate websites for example use this method.

I like very much this simple solution. There is really no need for additional modules. These ideas along with a Lightbox make the job.

I have tried the attached PHP code (content-field-field_mini_gallery.tpl.php.txt) inside a Drupal 7 site. The thumbnail images are placed side-by-side but studying the HTML shows that the images are not wrapped inside table cells at all. Not even a table can be seen.

Great ideas and I would love to see a code that works inside Drupal 7. What I need is a way that allows customizing distance between images, borders and backgrounds etc. The images need in fact to be placed inside a CSS configured table.

Tips are highly appreciated.

Simple idea, big difference. Thanks :-)

In Drupal 7 images are handled by Drupal core using the Fields API. I haven't looked at how you theme fields in Drupal 7. This looks like a decent starting point: API.Drupal.org - field.tpl.php.

Create a file such as:

  • field.tpl.php
  • field--field-type.tpl.php
  • field--field-name.tpl.php
  • field--content-type.tpl.php
  • field--field-name--content-type.tpl.php

src: http://api.drupal.org/api/drupal/modules--field--theme--field.tpl.php

then I modified the code slightly

<?php

$columns = 6;
$rows = array_chunk($items, $columns);
?>

<?php foreach ($rows as $row_number => $columns): ?>
<?php
$row_class = 'row-' . ($row_number + 1);
if ($row_number == 0) {
$row_class .= ' row-first';
}
if (count($rows) == ($row_number + 1)) {
$row_class .= ' row-last';
}
?>
">
<?php foreach ($columns as $column_number => $item): ?>
">
<?php print render($item); ?>

<?php endforeach; ?>

<?php endforeach; ?>

Not sure why the code is truncated, here you go - http://pastebin.com/NVMVXqx9

I have tried for over 3 months to get this right. No one told the story of the template files until you. Thanks a ton.

Hi, I am able to get what you need in the following way:
1. Assuming you have a custom content type with an image field, go to the "Configure" link on the image field.
2. Go to tab "Display fields".
3. Set the Teaser and Full node of your custom content type same. In my case both the "Teaser" and "Full node" are set to "Facybox:imagegallery_thumb image" where "imagegallery_thumb" is my Imagecache preset for a thumbnail.

Therefore I am able to have thumbnails in the teaser view of the node (in a Fancybox). Also when I go inside the link to the full node, I get the same thumbnails. In your case you will need to select the right Imagecache preset to make it a static image (without a popup)

I got the code for D7 working - thanx a lot. But I don't see the captions (title tags) coming up. The old code was <?php print $item['data']['title']; ?>, in divs called 'photo-title', but I see no equivalent in the D7 example.

<?php if ($item['#item']['title']) { print '' . $item['#item']['title'] . ''; } ?>