once again I would like to ask you for your kind help.

Basically I want to adjust the image caption below single post images. Instead of displaying the caption (post_excerpt), I would like to display the image title (post_title) (bold) and image description (post_content), similar like this:

With the kind help of @birgire I achieved that, using the img_caption_shortcode filter (LINK). Unfortunately, working with this solution, I found this isn't perfect.

Out of the box, when inserting an single image via the Wordpress visual editor, the image caption is inserted below the image. When editing the image, this caption can be adjusted individually (for this single instance) if necessary, as shown here: Changing caption

The problem with using the img_caption_shortcode filter is, that it replaces the content that would otherwise be returned no matter what, meaning that individual adjustments (as described above) are impossible. I would like to retain the original Wordpress behaviour in this case, but still replace the inserted image caption with the image title and description.

As of now, I do not have a starting point on how to achieve that. I imagine that I have to find a way to change the text output that is automatically inserted into the visual editor together with the single image. Can anybody help me with that or point me into the right direction? Any kind of help is greatly appreciated. Thank you.

EDIT: This is the code I'm currently using:

 * Plugin Name: Modified Image Caption
 * Description: Override The Image Caption With Image Title And Description
 * Plugin URI:  https://wordpress.stackexchange.com/a/258612/26350

namespace WPSE\Q258586;

add_action( 'init', [ new Caption, 'init' ] );

class Caption
    private $attachment_id ;

    public function init()
        add_filter( 'img_caption_shortcode',    [ $this, 'shortcode' ], 999, 3 );
        add_filter( 'shortcode_atts_caption',   [ $this, 'atts' ],      999, 3 );
    public function shortcode( $output, $attr, $content )
        if( isset( $attr['id'] ) && preg_match( '/attachment_\d+/i', $attr['id' ] ) )
            $this->attachment_id = str_replace( 'attachment_', '', $attr['id'] );

        return $output;

    public function atts( $atts, $pair )
        if( ! $this->attachment_id  )
            return $atts;

        $img = get_post( $this->attachment_id );

        if( is_a( $img, '\WP_Post' ) )
            $atts['caption'] = sprintf( 
                '<span class="title-css">%s</span>
                 <br><span class="description-css">%s</span>',
                esc_html( $img->post_title ),
                esc_html( $img->post_content )

        $this->id = null;

        return $atts;
  • Please post your code you are using currently so we don't have to follow through all of the comments in the prior thread.
    – WebElaine
    Commented Mar 16, 2017 at 16:46
  • Thank you for your comment. I added the code in my original post. Commented Mar 16, 2017 at 17:59
  • Thanks, that helps. It looks like you just need to add another conditional inside of if( is_a( $img, '\WP_Post' ) ): along the lines of, if a caption is set for this particular image, output that overriden caption; else (your original code which outputs the title and content).
    – WebElaine
    Commented Mar 16, 2017 at 20:05
  • You can check my alternative workaround for new uploaded images here. @HansWernersen
    – birgire
    Commented Mar 28, 2017 at 10:57
  • Thank you for your reply. I could change the output via your quick & dirty method by adressing the specific image ID, am I understanding that correctly? Unfortunately that would be a bit inconvienient, as it requires adding new code for every image I want to change the caption for. Also, it would be impossible to do whenever multiple users/authors (with even less coding knowledge than myself) are involved. @birgire Commented Mar 28, 2017 at 13:49


Your Answer

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

Browse other questions tagged or ask your own question.