• Resolved jbo.ciel

    (@jbociel)


    Hello,

    I try to modify the shortcode [caption] to add the description and the my custom field “copyright” to the <img>.

    Help with some posts i read to use html5 balise, i add the following code to my function.php:

    add_filter( 'img_caption_shortcode', 'cleaner_caption', 10, 3 );
    if ( !function_exists('cleaner_caption')) {
    	function cleaner_caption( $output, $attr, $content ) {
    
    		/* We're not worried abut captions in feeds, so just return the output here. */
    		if ( is_feed() )
    			return $output;
    
    		/* Set up the default arguments. */
    		$defaults = array(
    			'id' => '',
    			'align' => '',
    			'width' => '',
    			'caption' => ''
    		);
    
    		/* Merge the defaults with user input. */
    		$attr = shortcode_atts( $defaults, $attr );
    
    		/* If the width is less than 1 or there is no caption, return the content wrapped between the [caption]< tags. */
    		if ( 1 > $attr['width'] || empty( $attr['caption'] ) )
    			return $content;
    
    		/* Set up the attributes for the caption. */
    		$attributes = ( !empty( $attr['id'] ) ? ' id="' . esc_attr( $attr['id'] ) . '"' : '' );
    		$attributes .= ' class="wp-caption ' . esc_attr( $attr['align'] ) . '"';
    		$attributes .= ' style="width: ' . esc_attr( $attr['width'] ) . 'px"';
    
    		/* Open the caption <div>. */
    		$output = '<figure' . $attributes .'>';
    
    		/* Allow shortcodes for the content the caption was created for. */
    		$output .= do_shortcode( $content );
    
    		/* Add information to the $output. */
    		if ( get_featured_image_copyright() != '© ' ) {
    			$copyright = get_featured_image_copyright();
    		} else {
    			$copyright = get_post(get_post_thumbnail_id())->post_title;
    		};
    		$description = get_post(get_post_thumbnail_id())->post_content;
    		$title = get_post(get_post_thumbnail_id())->post_title;
    		$output = str_replace( '></a>','description="'.$description.'" title="'.$copyright.'" title-meta="'.$title.'"></a>',$output);
    
    		/* Append the caption text. */
    		$output .= '<figcaption class="wp-caption-text">' . $attr['caption'] . '</figcaption>';
    
    		/* Close the caption. */
    		$output .= '</figure>';
    
    		$output .= '<p class="wp-description-text">'.$description.'</p>';
    
    		/* Return the formatted, clean caption. */
    		return $output;
    	}
    } //endif !function_exists

    The problem is the code don’t work for all the post.
    For example when it works, i get the normal code:

    <figure class="wp-caption" itemscope itemtype="http://schema.org/ImageObject" >
    <a href="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2030/07/mon-beau-camion.jpg"  >
    <img width="625" height="315" src="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2030/07/mon-beau-camion.jpg" class="attachment-large wp-post-image" alt="If you say it loud enough, you’ll always sound precocious; Supercalifragilisticexpialidocious!" itemprop="contentURL" title-meta="Mon beau camion" title="© Mon copyright" description="Ma descritpion" /></a>
    <figcaption class="wp-caption-text" itemprop="description">Un régal!</figcaption></figure>

    For image post with link, i get this wrong code:

    <figure id="attachment_619" class="wp-caption alignnone" style="width: 640px">magnificPopup=Object { tClose="Fermer (Esc)", type="image", tLoading="Chargement de l'image #%curr%...", more...}
    <a href="http://wpthemetestdata.files.wordpress.com/2012/06/dsc20040724_152504_532.jpg">
    <img class="size-full wp-image-619" width="640" height="480" align="alignnone" href="http://wpthemetestdata.files.wordpress.com/2012/06/dsc20040724_152504_532.jpg" ]<a="" attachment_619"="" description="[caption id=" src="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2011/01/dsc20050901_105100_212.jpg" alt="Seed pods on stem, Woodvale">
    <img class="size-full wp-image-619" width="640" height="480" src="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2011/01/dsc20050901_105100_212.jpg" alt="Seed pods on stem, Woodvale">
    </a>
    Seed pods on stem, Woodvale[/caption]" title="" title-meta="Post Format Test: Image (Linked)">
    <figcaption class="wp-caption-text">Seed pods on stem, Woodvale</figcaption>
    </figure>

    For event organiser post, i get the same wrong code:

    <figure id="attachment_946" class="wp-caption alignnone" style="width: 1936px">magnificPopup=Object { tClose="Fermer (Esc)", type="image", tLoading="Chargement de l'image #%curr%...", more...}
    <a href="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2008/09/montagne-de-beurre.jpg">
    <img class="size-full wp-image-946" width="1936" height="2592" align="alignnone" href="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2008/09/montagne-de-beurre.jpg" ]<a="" attachment_946"="" description="Alors merci! [caption id=" src="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2008/09/montagne-de-beurre.jpg" alt="En haut de la montagne">
    <img class="size-full wp-image-946" width="1936" height="2592" src="http://jenfaisdestartines.mdl:8080/wp-content/uploads/2008/09/montagne-de-beurre.jpg" alt="En haut de la montagne">
    </a>
    Très belle photo[/caption]" title="" title-meta="Event 3">
    <figcaption class="wp-caption-text">Très belle photo</figcaption>
    </figure>

    For information, the problem is the same when the post is into the loop, and when it on a single page.

    Any idea will be welcomed.
    Thank you in advance,
    jB

Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz

    (@bcworkz)

    Probably the main problem is your str_replace() function is not finding the proper match in all situations. You need to echo the current value of $output and examine the results from all the various possible scenarios. Find something that works in all cases, either a series of conditionals or perhaps preg_replace().

    It also looks like shortcodes are leaking through do_shortcode() for some reason. The above exercise will reveal if this is the case or not. Another possibility is if there are nested caption shortcodes, your callback may in a sense be calling itself and scrambling things.

    Regardless, the first thing to do is check the output strings to see what you’re really dealing with.

    Thread Starter jbo.ciel

    (@jbociel)

    Thank you Bcworkz for your answer.

    I think about it this afternoon.
    Actually, preg_replace() doesn’t change anything. On the contrary.

    I conclude the issue came from this code:

    $description = get_post(get_post_thumbnail_id())->post_content;
    $title = get_post(get_post_thumbnail_id())->post_title;

    These variables call the information from the post and not for the attachment added into the caption.

    So i make a test with other information like _wp_attachment_image_alt:

    $attachment_id = get_post_thumbnail_id();
    $description = get_post_meta($attachment_id, '_wp_attachment_image_alt', true)

    No success.

    I am still looking for a solution.
    I try all the solutions i read and google results seems to be exhausted. I begin to think the caption <img> code is perfect for everybody…

    jB

    Moderator bcworkz

    (@bcworkz)

    Ah! I see now. I misunderstood where you were going with this. Yes, get_post() will get the post post_type related to the attachment, not the attachment post_type. To get that object you need to use get_post_type_object(). BTW, if you want the caption, it is in the post_excerpt column.

    The other issue is a caption in any particular post may not be the one stored with the attachment, it may be arbitrary text contained only in the parent post’s content. This is where I thought you were going initially.

    There’s a lot of possible text strings that could represent the caption, so it’s difficult to capture those variations with a single str_replace() function. If you’re clever with RegExps, it may be possible to adapt to all these variants with a single preg_replace() call. I wasn’t suggesting a straight substitution for str_replace() but a special RegExp sequence that takes the place of multiple “if-this-condition-exists-then-replace-this-string” sort of sequences.

    You must identify all the possible input variations in order to have a successful replacement for any condition.

    Just because you can’t find information about this does not mean everyone is happy the the current state. It could mean people are not ambitious enough to seek a better solution. People these days seem to readily settle for something that is merely good enough instead of aspiring for the best :/

    Thread Starter jbo.ciel

    (@jbociel)

    Hello bcworkz,

    I got it!

    First of all, i made a small step this morning: the problem which break the code was not due to the post type. But it was conditioned by the thumbnail presence, as my variables $description and $title use the thumbnail id.

    So i work on the attachment id and finally, i get this code which work perfectly in all the situations i tested:

    add_filter( 'img_caption_shortcode', 'cleaner_caption', 10, 3 );
    if ( !function_exists('cleaner_caption')) {
    	function cleaner_caption( $output, $attr, $content ) {
    
    		/* We're not worried abut captions in feeds, so just return the output here. */
    		if ( is_feed() )
    			return $output;
    
    		/* Set up the default arguments. */
    		$defaults = array(
    			'id' => '',
    			'align' => '',
    			'width' => '',
    			'caption' => ''
    		);
    
    		/* Merge the defaults with user input. */
    		$attr = shortcode_atts( $defaults, $attr );
    		$attachment = preg_split( "/_/", esc_attr( $attr['id'] ) ); // Return attachment_xxx
    		$attachment_id = $attachment[1];
    
    		/* If the width is less than 1 or there is no caption, return the content wrapped between the [caption]< tags. */
    		if ( 1 > $attr['width'] || empty( $attr['caption'] ) )
    			return $content;
    
    		/* Set up the attributes for the caption. */
    		$attributes = ( !empty( $attr['id'] ) ? ' id="' . esc_attr( $attr['id'] ) . '"' : '' );
    		$attributes .= ' class="wp-caption ' . esc_attr( $attr['align'] ) . '"';
    		$attributes .= ' style="width: ' . esc_attr( $attr['width'] ) . 'px"';
    
    		/* Open the caption <div>. */
    		$output = '<figure' . $attributes .'>';
    
    		/* Allow shortcodes for the content the caption was created for. */
    		$output .= do_shortcode( $content );		
    
    		/* Add information to the $output. */
    		$description = get_post($attachment_id)->post_content;
    		$title = get_post($attachment_id)->post_title;
    		if ( get_featured_image_copyright() != '© ' ) {
    			$copyright = get_featured_image_copyright($attachment_id);
    		} else {
    			$copyright = $title;
    		};		
    
    		$output = str_replace( '></a>','description="'.$description.'" title="'.$copyright.'" title-meta="'.$title.'"></a>',$output);
    
    		/* Append the caption text. */
    		$output .= '<figcaption class="wp-caption-text">' . $attr['caption'] . '</figcaption>';
    
    		/* Close the caption. */
    		$output .= '</figure>';
    		$output .= '<p class="wp-description-text">'.$description.'</p>';
    
    		/* Return the formatted, clean caption. */
    		return $output;
    
    	}
    } //endif !function_exists

    That’s all.

    Thank you for your helpful answers.

    jB

Viewing 4 replies - 1 through 4 (of 4 total)

The topic ‘Image caption // add attribute to img’ is closed to new replies.