Currently this is the (default) Wordpress image output:

Float left, with caption, link to img

<figure id="attachment_10220" style="width: 167px;" class="wp-caption alignleft">
    <a href="http://link-to-my-image.jpg"><img class="wp-image-10220 size-medium" src="http://link-to-my-image-167x251.jpg" alt="" width="167" height="251"></a>
    <figcaption class="wp-caption-text">My caption</figcaption>

Float right, without caption, link to img

<a href="http://link-to-my-image.jpg" class="img-link">
    <img class="alignright size-medium wp-image-10214" src="http://link-to-my-image-257x386.jpg" alt="" width="257" height="386">

Float left, without caption, no link

<img class="alignleft wp-image-10218" src="http://link-to-my-image.jpg-167x251.jpg" alt="" width="167" height="251">

First of all I'd like to know where the output of these images is defined, what functions should I look at? My goal is to make the output more uniform:

  • Wrap each image in a figure-tag (like the first example)
  • Do not add any style attributes
  • Add float class (alignleft, alignright) to the figure tag
  • Don't output attachment (attachment_xxx) or image IDs (wp-image-xxx)
  • Remove any height and width attributes from the images

Final expected output based on above examples:

<figure class="wp-caption alignleft">
    <a href="http://link-to-my-image.jpg">
        <img class="size-medium" src="http://link-to-my-image-167x251.jpg" alt="">
    <figcaption class="wp-caption-text">My caption</figcaption>
<figure class="alignright">
    <a href="http://link-to-my-image.jpg">
        <img class="size-medium" src="http://link-to-my-image-257x386.jpg" alt="">
<figure class="alignleft">
    <img src="http://link-to-my-image.jpg-167x251.jpg" alt="">
  • you talking about featured image output or the images add to post/page content. Featured image ouput can be easily modified with theme and the_post_thumbnail() function parameters.
    – Vikram
    Apr 16, 2015 at 4:10
  • post the url to check the structure if possible
    – Vikram
    Apr 16, 2015 at 4:11
  • @Vikram What do you mean by "post the url"? I can't be more clear than my example. Apr 16, 2015 at 17:51
  • Paste the url of page here.
    – Vikram
    Apr 17, 2015 at 3:29
  • @Vikram What page. I can't be more clear than my examples so I don't see the point. Apr 17, 2015 at 8:18

1 Answer 1


Lets start with your first code. If you add texts, captions etc. a shortcode will be generated: [caption] The function img_caption_shortcode() in wp-content/media.php is responsible to execute the shortcode. But this shortcode is only produced, when you use captions. Otherwise, it will be simply inserted the <a>- and <img>-Tag.

who decides, what gets inserted?

There is an interesting ajax request taking place, once you add a media file: send-attachment-to-editor. It sends all the data like 'image-size', 'url', 'html'...

The function wp_ajax_send_attachment_to_editor() which can be found in wp-admin/includes/ajax-actions.php is called by this ajax request. This functions attaches the image for example to the post. More interesting for us: This function creates the HTML, which will be posted in the editor. So, here it is decided, whether the [caption] shortcode or a simple <img>-Tag will be used.

The filter media_send_to_editor

Good for us since wp_ajax_send_attachment_to_editor() uses the filter media_send_to_editor to give us the chance to alter this code. Three parameters are given: - the current HTML output - the Attachment ID - the information, how big the image is, the align...

Just as an example:

 add_filter( 'media_send_to_editor', 'test_media', 10, 3 );
 function test_media( $html, $id, $attachment ){
    return '<a href="http://example.com">TEST</a>';

This would always print the Link http://example.com/

I hope this helps you as a start.

A "better" shortcode

To receive now the output, you want, I would suggest the following:

  add_filter( 'media_send_to_editor', 'use_always_caption', 10, 3 );
     function use_always_caption( $html, $id, $attachment ){
        $post = get_post( $id );
        //Return if its not an image
        if ( 'image' != substr( $post->post_mime_type, 0, 5 ) )
            return $html;
        $rel = '';
        $url =  isset( $attachment['url'] ) ? $attachment['url'] : '';

        if ( strpos( $url, 'attachment_id') || get_attachment_link( $id ) == $url )
            $rel = ' rel="attachment"';

        $align = isset( $attachment['align'] ) ? $attachment['align'] : 'none';
        $size = isset( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
        $alt = isset( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
        $caption = ' ';
        if( isset( $attachment['post_excerpt'] ) && ! empty( $attachment['post_excerpt'] ) )
            $caption = $attachment['post_excerpt'];
        $title = ''; // We no longer insert title tags into <img> tags, as they are redundant.
        add_filter( 'get_image_tag', 'remove_id_from_class_and_hw', 10, 6 );
        $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
        remove_filter( 'get_image_tag', 'remove_id_from_class_and_hw', 10, 6 );
        $html = preg_replace( '^toremove--width="(.*)"--toremove^', '', $html );
        return $html;

     function remove_id_from_class_and_hw( $html, $id, $alt, $title, $align, $size ){
         list( $img_src, $width, $height ) = image_downsize( $id, $size );
         $class = 'align' . esc_attr( $align ) .' size-' . esc_attr( $size );
         return '<img src="' . esc_attr( $img_src ) . '" alt="' . esc_attr( $alt ) . '" ' . $title . ' class="' . $class . '" toremove--width="' . $width . '" height="' . $height . '"--toremove />';

     remove_shortcode( 'caption' );
     add_shortcode( 'caption', 'better_img_caption_shortcode' );
     function better_img_caption_shortcode( $attr, $content = null ){
        if ( ! isset( $attr['caption'] ) ) {
            if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
                $content = $matches[1];
                $attr['caption'] = trim( $matches[2] );

        $output = apply_filters( 'img_caption_shortcode', '', $attr, $content );
        if ( $output != '' )
            return $output;

        $atts = shortcode_atts( array(
            'id'      => '',
            'align'   => 'alignnone',
            'width'   => '',
            'caption' => '',
            'class'   => '',
        ), $attr, 'caption' );

        $atts['width'] = (int) $atts['width'];
        if ( $atts['width'] < 1 )
            return $content;

        $class = trim( 'wp-caption ' . $atts['align'] . ' ' . $atts['class'] );

        $figcaption = '';
        if( ! empty( $atts['caption'] ) )
            $figcaption = '<figcaption class="wp-caption-text">' . $atts['caption'] . '</figcaption>';
        return '<figure class="' . esc_attr( $class ) . '">'
            . do_shortcode( $content ) . $figcaption . '</figure>';


I've copy-pasted a bit :)

So, what I do: With the filter media_send_to_editor I force WordPress to always use the [caption]-Shortcode. We alter a bit the image output by using the filter get_image_tag which is used by the function get_image_tag() to create the <img>-Tag. This function can be found in wp-include/media.php. Since I didn't wanted to create the whole shortcode and leave WordPress to do it, I needed to leave the width and height (you should leave it anyway, i think) because the caption creation done by image_add_caption() ( to be found in wp-admin/includes/media.php) needs these values from the string. I added an ugly toremove-- and remove it later on.

In a second step, I remove the existing [caption]-Shortcode and overwrite it with my own. My own is basically the same, but I removed the ID- and the Style-Attribute. I stick to the [caption]-Shortcode, so once the user disables the plugin, the pictures would still show up in a reasonable way.


  • Hi there, so I got around to testing this and the first part works as expected: the unnecessary classes and such are removed! A big problem, however, is that there is no figure wrapper to the elements (see my examples above). Even when I add a caption, the figure-tags don't output, nor the caption itself. It's left out. Subsequently the align classes are nowhere to be found either. Apr 15, 2015 at 5:57
  • Just letting you know that the bounty will end tomorrow but that your current answer doesn't solve my problem. Apr 17, 2015 at 8:19
  • hi bram! the [caption] shortcode is not placed in the editor or the [caption] is not executed correctly? I just tried it again and it works for me Apr 17, 2015 at 8:51
  • Well I simply used the code under "A better shortcode" in my functions.php and expected things to work by themselves. As I commented, the output of a figure tag and the figcaption tag doesn't work unfortunately. Apr 17, 2015 at 8:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.