Lightbox2 - Custom integration with CCK Imagefield and Imagecache
Imagecache/Imagefield basics
If you examine imagecache.module, you will find the theme_imagecache function:
theme_imagecache($namespace, $path, $alt = '', $title = '', $attributes = null)
Here is the basic, minimum, formatting required to print out a single imagefield image with an imagecache preset in your .tpl file:
<?php
print theme('imagecache', 'name_of_your_imagecache_preset', $field_name_of_your_cck_imagefield_field[0]['filepath']);
?>Wrapping the basics in Lightbox2
To display a single image in a lightbox, you can just wrap the image in an a tag with a rel="lightbox[photo_gallery]" attribute in it. The tricky part is writing out the link to the path to the imagecache preset for the image you want displayed in the lightbox. Here is the basic pattern to do this manually:
<?php
$lightbox_path = imagecache_create_url($lightbox_preset, $item['filepath'] );
$imagecache_image = theme('imagecache', 'name_of_your_thumbnail_imagecache_preset', $field_name_of_your_cck_imagefield_field[0]['filepath']);
print '<a rel="lightbox[my_gallery]" alt=" " title=" " href="'.$lightbox_path.'">'. $imagecache_image .'</a>';
?>However, Lightbox2 now comes with the following function:
function theme_imagefield_image_imagecache_lightbox2($view_preset, $field, $item, $node, $rel = 'lightbox')
Here is how you would call your image using this function:
<?php
$field_name_of_your_cck_imagefield_field[0]['lightbox_preset'] = 'name_of_your_imagecache_preset_for_lightbox';
print theme('imagefield_image_imagecache_lightbox2', 'name_of_your_thumbnail_imagecache_preset', $field_name_of_your_cck_imagefield_field[0]['filepath'], $field_name_of_your_cck_imagefield_field[0], $node, $rel = 'lightbox');
?>Multi-value Imagefields + Imagecache + Lightbox2
What if you want to display a bunch of images in multiple value imagefield to create a spiffy little photo gallery for your Content Type? While there is Imagefield Gallery module, it doesn't work if, like me, you have multiple imagefields in your Content Type.
To accomplish this task. We'll need to loop through each of the objects in our imagefield array. We are going to force the imagecache preset here, as the Lightbox2 function behaves strangely in this regards. Here is how we do it.
<?php
foreach((array)$node->field_photo_gallery as $item) {
$item['lightbox_preset'] = 'name_of_your_lightbox_imagecache_preset';
print theme('imagefield_image_imagecache_lightbox2', 'name_of_your_thumbnail_imagecache_preset', 'field_name_of_your_cck_imagefield_field', $item, $node, $rel = 'lightbox');
}
?>Practical example
OK, let's get practical. In this example, I am wanting to display the image from my CCK imagefield field_photo_gallery using the imagecache preset square_thumb for my thumbnails and lightbox for the larger images to display in the slideshow. This code resides in my node-my_node_type.tpl file in my theme directory. I've broken out the variables outside the print statement for better code reuse and am using the longhand version instead of the lightbox2 function in order to control the formatting a bit more:
<?php if ($field_photo_gallery[0] != '' && ($teaser != 1) ): ?>
<div id="photo-gallery">
<h3>PHOTO GALLERY</h3>
<?php
// the class is the same for all img tags, so we can declare it out of the loop
$thumbs_class['attributes']['class'] = 'gallery-thumbs';
foreach((array)$node->field_photo_gallery as $item) {
// construct the path to the lightbox image using a function from the imagecache module
// this creates valid URLs dynamically, so your code will still work if you move your files directory
$lightbox_preset = 'lightbox'; //the name of the imagecache preset to display in the lightbox
$lightbox_path = imagecache_create_url($lightbox_preset, $item['filepath'] );
$imagecache_image = theme('imagecache', 'square_thumb', $item['filepath'], $alt = 'gallery item', $title, $thumbs_class['attributes']);
// Creating a custom title on hover and caption in the lightbox. Create some custom alt tags too if you like
// Use check_plain to avoid XSS.
$caption = check_plain($item['title']).' <br /> '. check_plain($node->title) .' PHOTO GALLERY. <br /> Use right and left arrows or the mouse to navigate';
$title = check_plain($item['title']);
// finally, let's put it all together
print '<a class="gallery-thumbs" title="'.$caption.'" rel="lightbox[photo_gallery]" alt=" " href="'.$lightbox_path.'">'. $imagecache_image .'</a>';
}
?>
<div class="clear-block"></div>
</div> <!-- #/photo-gallery -->
<?php endif; ?>then you can add some nice css like so:
a.gallery-thumbs, #photo-gallery a {
display:block;
float: left;
margin: 5px 5px 5px 0;
padding:5px;
border:1px solid #ccc;
line-height:1em;
}
a.gallery-thumbs:hover, #photo-gallery a:hover {
background:#CCEE00;
}
CCK multiple values
I have a content type with a imagefield 'field_bilder' this field has multiple values.
Now I would like to see only one picture and then the hyperlink on this picture should open lightbox configured so that the user
can see all picture (using arrow or mouse).
here is what I did.
<?php$item = $node->field_bilder[0];
$item['lightbox_preset'] = 'fast_gallery_big';
print theme('imagefield_image_imagecache_lightbox2', 'fast_gallery_thumb', 'field_bilder', $item, $node, $rel = 'lightbox[bilder]');
?>
but I see only one picture.
only first one
here the version to show only the first picture of each node and hide the others
nees css like this:
#hide {
display: none;
}
<?php
$cur_id = 0;
foreach((array)$node->field_bilder as $item) {
// construct the path to the lightbox image using a function from the imagecache module
// this creates valid URLs dynamically, so your code will still work if you move your files directory
$lightbox_preset = 'product_big'; //the name of the imagecache preset to display in the lightbox
$lightbox_path = imagecache_create_url($lightbox_preset, $item['filepath'] );
$imagecache_image = theme('imagecache', 'product_thumb', $item['filepath'], $alt = 'galerie bild', $title, $thumbs_class['attributes']);
// Creating a custom title on hover and caption in the lightbox. Create some custom alt tags too if you like
// Use check_plain to avoid XSS.
$caption = check_plain($item['title']).' <br /> '. check_plain($node->title) .' Bilder. <br /> weiter mit <> Taste oder Maus';
$title = check_plain($item['title']);
// finally, let's put it all together
// if this is the first picture display it
if ($node->field_bilder[0][fid] != $cur_id){
print '<a class="gallery-thumbs" title="'.$caption.'" rel="lightbox[' . $item[nid] . ']" alt=" " href="'.$lightbox_path.'">'. $imagecache_image .'</a>';
$cur_id = $item[fid];
}
else {
// print a hidden link for all other
print '<a id="hide" rel="lightbox[' . $item[nid] . ']" alt=" " href="'.$lightbox_path.'">'. $imagecache_image .'</a>';
}
}
?>
kind regards
stoltoguzzi
Thank you, stoltoguzzi. I
Thank you, stoltoguzzi.
I used this today and it makes my day.
I only changed one thing: use
class="hide"instead ofid="hide"to make it valid xhtml.how I show only one image on a multi-value field in a view
I was struggling quite a lot and ended up changing a lightbox formatter. My setup consists of a multi-value CCK ImageField which was loaded by ImageCache in a View (version 2) and prettied up with Lightbox2. Here is the complete function from lightbox2.formatter.inc:
<?php
function theme_imagefield_image_imagecache_lightbox2($view_preset, $field_name, $item, $node, $rel = 'lightbox', $args = array()) {
if (!isset($args['lightbox_preset'])) {
$args['lightbox_preset'] = 'original';
}
// Can't show current node page in a lightframe on the node page.
// Switch instead to show it in a lightbox.
if ($rel == 'lightframe' && arg(0) == 'node' && arg(1) == $node->nid) {
$rel = 'lightbox';
}
$orig_rel = $rel;
// Unserialize into original - if sourced by views.
$item_data = $item['data'];
if (is_string($item['data'])) {
$item_data = unserialize($item['data']);
}
// Set up the title.
$image_title = $item_data['description'];
$image_title = (!empty($image_title) ? $image_title : $item_data['title']);
$image_title = (!empty($image_title) ? $image_title : $item_data['alt']);
$image_tag_title = '';
if (!empty($item_data['title'])) {
$image_tag_title = $item_data['title'];
}
if (variable_get('lightbox2_imagefield_use_node_title', FALSE)) {
$node = node_load($node->nid);
$image_title = $node->title;
}
// Enforce image alt.
$image_tag_alt = '';
if (!empty($item_data['alt'])) {
$image_tag_alt = $item_data['alt'];
}
elseif (!empty($image_title)) {
$image_tag_alt = $image_title;
}
// Set up the caption.
$node_links = array();
if (!empty($item['nid'])) {
$attributes = array();
$attributes['id'] = 'node_link_text';
$target = variable_get('lightbox2_node_link_target', FALSE);
if (!empty($target)) {
$attributes['target'] = $target;
}
$node_link_text = variable_get('lightbox2_node_link_text', 'View Image Details');
if (!empty($node_link_text)) {
$node_links[] = l($node_link_text, 'node/'. $item['nid'], array('attributes' => $attributes));
}
$download_link_text = check_plain(variable_get('lightbox2_download_link_text', 'Download Original'));
if (!empty($download_link_text) && user_access('download original image') && user_access('view imagefield uploads')) {
$node_links[] = l($download_link_text, $item['filepath'], array('attributes' => array('target' => '_blank', 'id' => 'download_link_text')));
}
}
$caption = $image_title;
if (count($node_links)) {
$caption .= '<br /><br />'. implode(" - ", $node_links);
}
if (isset($args['caption'])) {
$caption = $args['caption']; // Override caption.
}
if ($orig_rel == 'lightframe') {
$frame_width = variable_get('lightbox2_default_frame_width', 600);
$frame_height = variable_get('lightbox2_default_frame_height', 400);
$frame_size = 'width:'. $frame_width .'px; height:'. $frame_height .'px;';
$rel = preg_replace('/\]$/', "|$frame_size]", $rel);
}
// Set up the rel attribute.
$full_rel = '';
$imagefield_grouping = variable_get('lightbox2_imagefield_group_node_id', 1);
if ($imagefield_grouping == 1) {
$full_rel = $rel .'['. $field_name .']['. $caption .']';
}
elseif ($imagefield_grouping == 2 && !empty($item['nid'])) {
$full_rel = $rel .'['. $item['nid'] .']['. $caption .']';
}
elseif ($imagefield_grouping == 3 && !empty($item['nid'])) {
$full_rel = $rel .'['. $field_name .'_'. $item['nid'] .']['. $caption .']';
}
elseif (isset($args['rel_grouping'])) {
$full_rel = $rel .'['. $args['rel_grouping'] .']['. $caption .']';
}
else {
$full_rel = $rel .'[]['. $caption .']';
}
// hide all photos except for the first one before opening the lightbox
if ($item['fid'] == $node->{$field_name}[0]['fid']) {
$link_attributes = array(
'rel' => $full_rel
);
}
else {
$link_attributes = array(
'rel' => $full_rel,
'class' => 'lightbox_hide_image'
);
}
$attributes = array();
if ($view_preset == 'original') {
$image = theme('lightbox2_image', $item['filepath'], $image_tag_alt, $image_tag_title, $attributes);
}
else {
$image = theme('imagecache', $view_preset, $item['filepath'], $image_tag_alt, $image_tag_title, $attributes);
}
if ($args['lightbox_preset'] == 'node') {
$output = l($image, 'node/'. $node->nid .'/lightbox2', array('attributes' => $link_attributes, 'html' => TRUE));
}
elseif ($args['lightbox_preset'] == 'original') {
$output = l($image, file_create_url($item['filepath']), array('attributes' => $link_attributes, 'html' => TRUE));
}
else {
$output = l($image, imagecache_create_url($args['lightbox_preset'], $item['filepath']), array('attributes' => $link_attributes, 'html' => TRUE));
}
return $output;
}
?>
The only code that I have changed in there is close to the end:
<?php// hide all photos except for the first one before opening the lightbox
if ($item['fid'] == $node->{$field_name}[0]['fid']) {
$link_attributes = array(
'rel' => $full_rel
);
}
else {
$link_attributes = array(
'rel' => $full_rel,
'class' => 'lightbox_hide_image'
);
}
?>
Maybe someone wants to add this formatter to the standard distribution?
I did not find another way to do this (e.g. in a custom tpl file) which is why I chose this approach.
Regards,
Dennis
Just was I was looking for...
Just was I was looking for... Except I wanted to do the opposite. I wanted to display one large image grouped with a few thumbnails below. Seemed simple enough except the problem is I also had a thumbnail of the large image above. I messed around with your code and sorry for my sloppy ways but here's what I did in order to exclude the large image being printed again as a thumbnail.
<?php// PRINT IMAGES IF THEY EXIST
if ($field_image_upload) {
$node->field_image_upload[0][fid] = 1;
$i = $node->field_image_upload[0][fid];
// SHOW MAIN ARTICLE IMAGE
print '<a href="/fp_files/imagecache/article/article_images/' . $field_image_upload[0]['filename'] . '" ' . '" ' . 'title="' . $image['title'] . '" rel="lightbox[group]">' . theme('imagecache', 'article_main', $field_image_upload[0]['filepath']) . '</a>';
if (is_array($field_image_upload) && count($field_image_upload)) {
foreach($field_image_upload as $delta => $image) {
if ($i++ != 1){
// SHOW THUMBNAIL SIZE IMAGES
print '<a href="/fp_files/imagecache/article/article_images/' . $image['filename'] . '" ' . '" ' . 'title="' . $image['title'] . '" rel="lightbox[group]">' . theme('imagecache', 'teasers', $image['filepath']) . '</a>';
}
}
}
}
?>
Imagecache description?
I don't know if anyone is still checking this page, but I want to say this really saved the day! I've been pulling my hair out for weeks trying to figure out how to do this.
One question though, is there a way to print the description under the images in both the "single" view and the lightbox view?
So it would be:
Image
Image description
and then when you click you'd get the same effect in the lightbox?
Imagefield allows you to enter a description when you upload the photo that makes for a nice way to do captions for each image uploaded.
Perhaps <?php print
Perhaps
<?phpprint $image['description']
?>
How to display content inline?
This is working great but how do I wrap content inline? Around the image.
Item descriptions as captions
I also can't get this to work properly.
It have a nice gallery implemented with this method, but the caption call is not bringing in the description I entered for each image in the image uploader.
Any ideas?
Same here
I'm having the same problem -- the description field provided in the code pulls the node title, not the photo title or description. I've tried this to no avail:
print $item['description'];...but that's just blank. I've done a
var_dump($item);and it shows that "description" is the correct name, but yet nothing displays when I try to print it.try something along the lines
try something along the lines of $image[0]['data']['description']
That did it -- in my case I
That did it -- in my case I used $item['data']['description'] since I'm using the $item array. Thanks very much!