• Resolved resunoiz

    (@resunoiz)


    Hi, in order to style properly an image with caption I’d like to add to wp-caption div the css classes of the image contained, as happens with the align class (when in a caption, the .alignleft class is transferred to wp-caption).

    is it possible?

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

    (@bcworkz)

    You mean when an image is inserted into post content through the media library, correct?

    If so, the ‘image_send_to_editor’ filter should work for you. While a lot of data is passed to your callback, to manipulate the class attributes you’ll be relying on PHP string functions to locate the proper terms and place them where needed.

    Thread Starter resunoiz

    (@resunoiz)

    never read about this filter. how does it works?
    yes, through media library.

    Thread Starter resunoiz

    (@resunoiz)

    tried some samples & tried, not exactly what I want.

    try to explain what I need with a sample…

    a “simple” image:
    imgres

    same image, with caption:
    <div id=”attachment_1133″ style=”width: 166px” class=”wp-caption alignleft”>
    imgres
    <p class=”wp-caption-text”>caption</p>
    </div>

    as you can see, the alignleft class on the image is “transferred” to the caption div. I doon’t know exactly how it works: what I need is to transfer the size-full class from the img tag to the div with class wp-caption alignleft.

    as result:
    <div id=”attachment_1133″ style=”width: 166px” class=”wp-caption alignleft size-full”>
    imgres
    <p class=”wp-caption-text”>caption</p>
    </div>

    Moderator bcworkz

    (@bcworkz)

    I think I see, thanks for the additional explanation. I had mis-remembered how captions actually work. I obviously suggested the wrong filter. My apologies.

    The filter you want is actually ‘img_caption_shortcode’, which is used to override the default caption shortcode output. Your callback is passed 3 parameters. First is an empty string which you of course ignore, then an array that includes alignment and caption data, and finally the full img tag HTML alone, without any other content. In using this data, your callback needs to build the actual HTML to be returned by the caption shortcode. Once it’s built, return it and it’ll be used instead of the default HTML.

    Thread Starter resunoiz

    (@resunoiz)

    the problem is: how tell the ‘img_caption_shortcode’ “take the class of the image you contain”?

    Moderator bcworkz

    (@bcworkz)

    You need to build the actual HTML within the callback, so you can assign whatever classes you want, anywhere you want. The img tag passed has the size class and image ID class already, but the same data is available in the passed data array, which is easier to use. Assuming HTML5 style, something like this in your filter callback function (assuming $attr and $tag are the collected parameters of your callback function):
    return "<figure class=\"$attr['align']\">$tag<figcaption class=\"$attr['align']\">$attr['caption']</figcaption></figure>";
    I’ve omitted other elements WP usually adds, showing only how the alignment class is added to both places. To match the usual WP HTML, you’ll also need to add an id attribute, the wp_caption and wp_caption_text classes, and the width style attribute. Everything you need is in the 2 passed variables. You can also add any other tags and attributes that might be helpful for your theme.

    In case you need help with hooking into filters, see the Plugin Handbook. The same concept applies to theme code.

    Thread Starter resunoiz

    (@resunoiz)

    I’m afraid is a bit over my knowledge….
    tried to add the filter, but i can’t figure out ho to pass the size-full class (what I actually need) to the caption class or id.

    I tried to add this code to functions.php to dive to id caption the same class of the image but nothing happens

    add_filter( 'img_caption_shortcode', 'my_img_caption_shortcode', 10, 3 );
    
    function my_img_caption_shortcode( $empty, $attr, $content ){
    	$attr = shortcode_atts( array(
    		'id'      => '',
    		'align'   => 'alignnone',
    		'width'   => '',
    		'caption' => '',
    		'class' => ''
    	), $attr );
    
    	if ( 1 > (int) $attr['width'] || empty( $attr['caption'] ) ) {
    		return '';
    	}
    
    	if ( $attr['id'] ) {
    		$attr['id'] = 'id="' . esc_attr( $attr['id'] ) . '" ';
    	}
    
    	return '<div ' . $attr['class']
    	. 'class="wp-caption ' . esc_attr( $attr['align'] ) . '" '
    	. 'style="max-width: ' . ( 10 + (int) $attr['width'] ) . 'px;">'
    	. do_shortcode( $content )
    	. '<p class="wp-caption-text">' . $attr['caption'] . '</p>'
    	. '</div>';
    
    }

    honestly I don’t know exactly how to make it work

    Moderator bcworkz

    (@bcworkz)

    Don’t despair, you are sooo close! You’ve done well so far.

    Nothing happens? Aside from the size issue and some minor things, your code works fine on my site. Are you looking in the right place? The post content does not change, the change occurs when the post is output. Load a post with a captioned image and check the HTML source in your browser.

    To determine what size was inserted, use string functions (preg_match() for example) to find the img tag’s size class and extract it for use in the caption output. While it’s more involved, you could instead get all the attachment meta data with wp_get_attachment_metadata() and identify which size key has a matching width value. I’d consider this a more formal approach, but not necessarily better.

    About those minor things. What you have doesn’t hurt anything, but there’s a couple things that don’t need to happen unless there’s more to your situation than I’m aware of. Why redefine $attr[‘id’] if you do not use it in the returned value? If you did use it, I believe the filter will reliably provide the ID every time, and in any case using shortcode_atts() will guarantee some value, so there’s no reason for if ( $attr['id'] )

    The passed img tag (as $content) should never have a shortcode in it AFAIK, so passing it through do_shortcode() serves no purpose. As I said, these do no harm, but are probably unnecessary unless there’s more to your installation than I realize.

    Thread Starter resunoiz

    (@resunoiz)

    re-tried…does not work with the image size.

    how can I implemente that preg_match function? Do you can suggest me a sample/provide me one?

    Moderator bcworkz

    (@bcworkz)

    Not fully tested, but this should work:

    preg_match('/class=".*?(size-.*?)[\s|"]/', $content, $matches );
    
    return '<div ' . $attr['class']
    . 'class="wp-caption ' . esc_attr( $attr['align'] ) . '" '
    . 'style="max-width: ' . ( 10 + (int) $attr['width'] ) . 'px;">'
    . $content
    . '<p class="wp-caption-text '. $matches[1] .'">' . $attr['caption'] . '</p>'
    . '</div>';
    Thread Starter resunoiz

    (@resunoiz)

    nope..doesn’t work ??

    or, more probably, I don’t know how to implement it to give that class to the caption.

    add_filter( 'img_caption_shortcode', 'my_img_caption_shortcode', 10, 3 );
    
    function my_img_caption_shortcode( $empty, $attr, $content ){
    	$attr = shortcode_atts( array(
    		'id'      => '',
    		'align'   => 'alignnone',
    		'width'   => '',
    		'caption' => '',
    		'class' => ''
    	), $attr );
    
    	if ( 1 > (int) $attr['width'] || empty( $attr['caption'] ) ) {
    		return '';
    	}
    
    	if ( $attr['id'] ) {
    		$attr['id'] = 'id="' . esc_attr( $attr['id'] ) . '" ';
    	}
    
    	preg_match('/class=".*?(size-.*?)[\s|"]/', $content, $matches );
    
    return '<div ' . $attr['class']
    . 'class="wp-caption ' . esc_attr( $attr['align'] ) . '" '
    . 'style="max-width: ' . ( 10 + (int) $attr['width'] ) . 'px;">'
    . $content
    . '<p class="wp-caption-text '. $matches[1] .'">' . $attr['caption'] . '</p>'
    . '</div>';
    
    }
    Moderator bcworkz

    (@bcworkz)

    Huh, your code works on my site. My img tag class attribute:
    class="size-full wp-image-591"

    The “size-full” is extracted and placed in the caption p tag:
    <p class="wp-caption-text size-full">My image caption</p>

    You are looking at the output HTML, correct? Not the caption shortcode, which doesn’t change.
    Please post an example of your caption shortcode content (the part between [caption] and [/caption]). Maybe it’s different than default due to your theme or a plugin, so that the regexp in preg_match() needs adjustment.

    Thread Starter resunoiz

    (@resunoiz)

    yes, I look at theme output.

    maybe there’s something in the theme (i-craft) that “blocks” that attribute?

    the caption:
    [caption id="attachment_3271" align="alignleft" width="604"]

    the output page:
    https://www.dynamicsystem.fe.it/dynamic-system-ama-i-mattoncini-lego/

    ant the output code.
    <div class="wp-caption alignleft" style="max-width: 614px;"><a href="https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03.jpg" class="fancybox" rel="fancybox" title="Dynamic System ama i mattoncini Lego!"><img class="wp-image-3271 size-large" src="https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03-800x600.jpg" alt="03 800x600 Dynamic System ama i mattoncini Lego!" srcset="https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03-800x600.jpg 800w, https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03-300x225.jpg 300w, https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03-600x450.jpg 600w, https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03.jpg 960w" sizes="(max-width: 604px) 100vw, 604px" title="Dynamic System ama i mattoncini Lego!" width="604" height="453"></a><p class="wp-caption-text size-large">la piccola Marty con la sua creazione</p></div>

    for extreme clearness, the same image without caption:
    <a href="https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03.jpg"><img class="alignleft wp-image-3271 size-large" src="https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03-800x600.jpg" alt="03" width="604" height="453" /></a>

    as you see, it takes the align attribute, not the the size one.
    the code I’ve put in functions.php is the same as above.

    • This reply was modified 8 years, 3 months ago by resunoiz.
    Thread Starter resunoiz

    (@resunoiz)

    the entire caption (sorry I’ve forgot it!)

    [caption id="attachment_3271" align="alignleft" width="604"]<a href="https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03.jpg"><img class="wp-image-3271 size-large" src="https://www.dynamicsystem.fe.it/wp-content/uploads/2016/09/03-800x600.jpg" alt="03" width="604" height="453" /></a> la piccola Marty con la sua creazione[/caption]

    Moderator bcworkz

    (@bcworkz)

    Thank you for the extreme clearness ??

    I see the problem now. The problem is me (again).

    Try returning this version:

    return '<div ' . $attr['class']
    . 'class="wp-caption ' . esc_attr( $attr['align'] ) . ' ' . $matches[1] .'" '
    . 'style="max-width: ' . ( 10 + (int) $attr['width'] ) . 'px;">'
    . $content
    . '<p class="wp-caption-text">' . $attr['caption'] . '</p>'
    . '</div>';
Viewing 15 replies - 1 through 15 (of 19 total)
  • The topic ‘add the img classes to wp-caption’ is closed to new replies.