I can't figure out how to make captions appear under attached images in the node view. I know I can use Image Assist instead, but for the site I'm doing right now (and those I anticipate doing), Image Attach will work just beautifully for the end client. Am I missing something here?

Thanks for the great work, as always. Despite the maddening "speed bumps," Drupal is truly awesome.

Comments

jboeger’s picture

Same here! Can't figure it out. Thanks to whomever can help.

jboeger’s picture

Same here! Can't figure it out. Thanks to whomever can help.

steinmb’s picture

Status: Active » Fixed

Hi
I solved this by using http://drupal.org/project/image_caption. When you have installed this you need to make changes to your theme template.php. At the end of the file add:

/**
 * Theme an img tag for displaying the image.
 */
function zen_image_display($node, $label, $url, $attributes) {
    $attributes['class'] = "caption ". (isset($attributes['class']) ? $attributes['class'] : "");
  return theme('image', $url, $node->title, $node->title, $attributes, FALSE);
}

You need to replace "zen_image_display" with the name of your theme (theme_image_display). It wrappes a div around the image with the same width as the image. Quick to solve but took me days to figure it out ;)

Cheers
Stein Magne

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

bcobin’s picture

I'm reopening this - very close! Problem is that you have no choice whether or not to display the caption in Image Attach - the title appears even if the requested caption is blank or another value.

Awesome work, Stein - perhaps a tweak away! Thank you oh so much...

asb’s picture

Version: 5.x-2.0-alpha1 » 6.x-1.x-dev
Status: Closed (fixed) » Active

The template override from #3 causes captions to appear in every view with an embedded image.module image. With CSS I can fix every view manually by setting this to display: none;, but obviously this is terrible.

Is there a cleaner way to show image captions only in nodes?

Reopening for the current 6.x-1.x-dev release.

Thanks & greetings, -asb

joachim’s picture

Status: Active » Closed (won't fix)

I doubt this is possible.

If you want a caption on attached images, you'd be better off using the theme function that specifically does attached images. There is a new version of it in the -dev release.

asb’s picture

"the theme function that specifically does attached images"? This sounds like a suggestion targeted at developers, so I'll better remove the code from #3 from my theme and live without captions at all. Attached images are the only place where captions make sense IMHO. Good, some PHP memory saved ;-)

Greetings, -asb

joachim’s picture

At developers?

I just mean use a different theme function -- there is now one specifically for attached images. Sounds like exactly what you want.

asb’s picture

I would consider stuff like the code from #3 as "targeted at developers". Your mileage might vary ;)

/**
* Theme an img tag for displaying the image.
*/
function zen_image_display($node, $label, $url, $attributes) {
    $attributes['class'] = "caption ". (isset($attributes['class']) ? $attributes['class'] : "");
  return theme('image', $url, $node->title, $node->title, $attributes, FALSE);
}
joachim’s picture

It's just overriding theme functions: http://drupal.org/node/341628

This is a major part of getting the most out of customizing Drupal.

asb’s picture

@joachim:

I'm fully aware what theme overrides are, I've read quite a bit about them (e.g. in Front End Drupal by Emma Jane Hogbin and Konstantin Käfer), I'm using some where I found working snippets, and others have caused me quite some nightmares. But coding them myself from scratch is beyond me - working with dynamic arrays and modifying processing logic to me (and most site admins and themers I know) is coding. Or, as Stein put it in #3: Quick to solve but took me days to figure it out ;). It's quick to solve if you know how to code, for the rest of us it's nothing but trial and error (with potentially bizarre or worse results ;)

Greetings, -asb

joachim’s picture

With all due respect, it's really not that hard. It just requires a bit of patience and a clear head.

If you look at theme_image_attach_node_attached (in dev release), you'll find this line:

    $output .= l(image_display($image, $img_size), $link, array('html' => TRUE));

There's a fair bit of noise there, but you can see that it adds to the output the result of image_display, and image_display does what its name tells you.

Stick in a line after that:

    $output .= 'I iz in yr theme function adding to yr output';

and you now have a caption. Wrap it in some HTML if you like.

Of course that will give you the same caption for every image, which is no good. You want the title of each image. The way to find out how to do this is to install devel module and add:

dsm($image)

and investigate what is inside the $image variable. To save you the bother, I'll tell you that you want:

    $output .= $image->title;

You might have been able to deduce this by looking at what defines $image in the first place:

  // Output each image node.
  // We take them in reverse order because they are floated to the right, and we want the
  // apparent left to right order to be correct.
  $output = '';
  foreach (array_reverse($image_nodes) as $image) {

I put in lots of comments -- otherwise 6 months later I've forgotten what the code does. The foreach takes an array of $image_nodes -- hence nodes -- and sets each one in turn to $image. (BTW: there is no 'dynamic' distinction for arrays in PHP ;)

This sort of piecemeal frankenstein coding is exactly how a lot of us got started coding in PHP -- myself included :)

asb’s picture

Hi Joachim,

thank you for you explanations. Indeed I can follow to a certain point; with image-6.x-1.x-dev, I'm getting image captions without the image_caption module, when hacking ./modules/image/contrib/image_attach/image_attach.module and insert $output .= $image->title; as instructed. So this will work until image-6.x-1.x-dev is being updated, and I suspect that your point was to put this somehow into template.php. So far this simply gives me a pretty WSOD, but I'll continue my monkey thing and maybe accidentally stuble over something ;)

Greetings, -asb

Vidioterie’s picture

(my first comment ever on this site, so let me know if I'm doing something the wrong way)

Came across the same problem, found this issue, added the bits and pieces together and found a solution that works for me. Here it is!

Okay, so just to summarize the last two comments into one fool-proof (I think) solution:

1. Open modules/image/contrib/image_attach/image_attach.module in your favorite editor
2. Copy the entire function theme_image_attach_body and paste it into your template.php
3. Add the following code exactly before the return-statement:

$output .= '<div class="image-attach-caption">' . $image->title . '</div>'."\n";

Resulting in the following function (added a little comment as well):

function mytheme_image_attach_body($node, $iid) {
  $img_size = variable_get('image_attach_size_body_'. $node->type, IMAGE_THUMBNAIL);

  if ($img_size != IMAGE_ATTACH_HIDDEN) {
    drupal_add_css(drupal_get_path('module', 'image_attach') .'/image_attach.css');

    $image = node_load($iid);
    if (!node_access('view', $image)) {
      // If the image is restricted, don't show it as an attachment.
      return NULL;
    }
    $class = 'image-attach-body' . ($image->status ? '' : ' image-unpublished');
    $info = image_get_info(file_create_path($image->images[$img_size]));

    $output = '<div style="width: ' . $info['width'] . 'px" class="' . $class . '">';
    $output .= l(image_display($image, $img_size), "node/$iid", array('html' => TRUE));
    $output .= '</div>'."\n";

    // theme override: added this next line for displaying the CAPTION
    $output .= '<div class="image-attach-caption">' . $image->title . '</div>'."\n";

    return $output;
  }
}

Don't forget to replace "mytheme" with the machine-readable name of your theme.

Note that the caption is wrapped in a div with class "image-attach-caption".

Now the caption may appear at the top of your article, instead of under the image. This is because css that comes with image_attach adds a float:right to the img-tag, instead of the whole parent-div. The solution which worked for me (but might not work entirely satisfactory with multiple images):

Add the following CSS-code to your theme's CSS:

.image-attach-body {
	/* override module css */
	float: none;
	margin: 0px;
}
	
.all-attached-images {
	float: right;
	margin-left: 1em;
}

.image-attach-caption {
	...CSS definitions for your caption...
}

This was done using Drupal 6.16 with Image 6.x-1.0-beta5.

joachim’s picture

Yup, the above is pretty much spot on! Thanks for writing that up Vidioteri -- I'll add it to the handbook's section on theming unless you want to do that yourself.

The dev version of the code improves the HTML output -- the IMG tag is wrapped in a DIV with class image-attach-body and it's these that are floated -- hence you can add anything into that and it will float too.

Hmm I should probably roll another beta so people actually use this!

Vidioterie’s picture

Joachim, thanks for the thumbs up.
Great that the img-div-class thingie has been improved in dev.

Sure you can add this to the handbook section. I'm already figuring out so many things these days (trying to finish my first - and extremely complicated - drupal website), that I'd prefer not needing to figure out the handbook section ;-) even though I don't expect it to be too complicated.

I was wondering, should we maybe wrap the extra $content line in an if (isset($image->title)) {}, so it won't generate useless html code?

joachim’s picture

Nodes always have titles, and the incoming $image is a node object, so you'll always have title :)

I ought to say that the dev release is completely fine to use.

sam.foster’s picture

I've tried following #15

I'm using 6.x-1.x-dev, I've got the code showing up having added the theme function as described, and I can add a dummy caption but I can't work out if

$image->title

is still correct in order to pull out the title.

Any pointers...

Here's what I've got as my theme function

--- snip ---

function sky_image_attach_attached_images_node($nid, $image_nodes, $img_size, $teaser = FALSE) {
drupal_add_css(drupal_get_path('module', 'image_attach') . '/image_attach.css');

$options = array(
'size' => $img_size,
'link' => $teaser ? 'node' : 'image',
'attributes' => array(
'class' => 'image-attach-' . ($teaser ? 'teaser' : 'body'),
),
);

// We take the images in reverse order because they are floated to the right,
// and we want the apparent left to right order to be correct.
$output = theme('image_attach_attached_images', $nid, array_reverse($image_nodes), $options);

// Wrap output of potentially multiple images in a DIV.
if ($output && !$teaser) {
$output = '

' . $output . '
' . $image->title . 'This is a caption

';

}

return $output;
}

-- snip -----

joachim’s picture

A recent commit changed all the image attach theme functions again I'm afraid -- this was to accommodate the Views field of attached images.

One thing to bear in mind: do not print $image->title without running it through check_plain()!

sam.foster’s picture

Joachim

Thanks for the reply but I'm not sure it takes me further. Is the theme function I copied from the image_attach module the right one? I took it from the fresh download of the 6.1.1.x dev version

Should it work? Have I got the right syntax for displaying the image title?

Thanks in advance

Sam

joachim’s picture

> Is the theme function I copied from the image_attach module the right one

I don't know! Is it the theme function that's getting called?

> Have I got the right syntax for displaying the image title?

Looks like. What does it produce? If it produces the title, then it's right.

sam.foster’s picture

Yes it is the theme function that is called, at least if I alter the code in template.php and then reload the page I see the changes in the html (using Firebug to view that).

The title does not appear though. However if I put a dummy piece of text in place of the variable then I see that text - but of course that's for all the images, and as you pointed out in an earlier post that obviously not what I'm after!

Apologies if I'm coming over a bit thick - and I'd like to express my thanks for the module and the help you've given thus far.

Regards

Sam

joachim’s picture

Quickly reading your code in the comment above (BTW -- use CODE tags so it's readable another tim), $image is nowhere defined. It's not coming in, and it's not set. So obviously $image->title is a big nada. Check the theme function in the latest dev.

thomasmurphy’s picture

Hey, I tried this out, but I think now that was a bad idea as this caption module is just for image attach, right? So it won't work if I'm using image assist with TinyMCE? Does anyone know if there is a way of wrapping images added with image assist in DIVs with titles as the caption...?

gallegosj’s picture

Has anyone been able to get the override in #19 to work? Or is there another recommended fix? I'm still looking for a caption solution to this otherwise amazing module. Using version 1.1.

asb’s picture

@gallegosj: #15 worked for me for a while, then suddenly stopped working. I have given up on this a long time a ago (including the attempt to honor legal requirements like giving proper image credits). As the issue status says, it's a "won't fix".

joachim’s picture

> then suddenly stopped working

As I said further up, the theme functions had to be rejigged.