HTML tags in WordPress image caption

I’m developing a client website with WordPress (3.3) but have found that the image caption feature strips out any HTML tags.

The resulting caption is plain text which makes proper image crediting difficult. Also being a client website, WYSIWYG editing is required.

Read More

For example if my shortcode is:


<a href="http://example.com/image.jpg">
<img src="http://example.com/image-300x224.jpg" alt=""/>
</a>

The tags are stripped from the caption attribute like so:


<a href="http://example.com/image.jpg">
<img src="http://example.com/image-300x224.jpg" alt=""/>
</a>

The tags I’d most like to preserve are <em>, <sup>, <sub>, <span> and <a>.

I haven’t found any existing plugins to fix this except for links.

Any ideas on how to go about this and which functions to override?

Related posts

Leave a Reply

3 comments

  1. I’m glad that better support should be added in version 3.4 but for now I’ve fixed the issue by changing the behaviour of image insertion so that it doesn’t use the [caption] shortcode.

    Here’s what I added to functions.php:

    add_filter( 'disable_captions', create_function('$a', 'return true;') );
    
    function image_send_to_editor_2($html, $id, $caption, $title, $align, $url, $size, $alt) {
        if ( !$caption ) {
            return $html;
        } else {
            $width = 'auto';
            if ( preg_match( '/width="([0-9]+)/', $html, $matches ) ) {
                $width = $matches[1] . 'px';
            }
    
            $output = '<div id="attachment-' . $id . '" class="wp-caption align' . $align . '" style="width: ' . $width . ';">';
            $output .= $html;
            $output .= '<p class="wp-caption-text">' . $caption . '</p>';
            $output .= '</div>';
    
            return $output;
        }
    
    }
    
    add_filter('image_send_to_editor', 'image_send_to_editor_2', 10, 8);
    

    This works best with the TinyMCE Advanced plugin with its option to stop removing (and adding) <p> and <br /> tags enabled.

  2. Okay, your problem seems interesting.

    One thing I could think of is:

    [caption caption="caption1"]
    <a href="http://example.com/image.jpg">
    <img src="http://example.com/image-300x224.jpg" alt=""/>
    </a>
    [/caption]
    

    Store a custom meta field for the post with name ‘caption1’ and your HTML caption. Use a filter on the_content() to convert all caption1 into your HTML caption by pulling it from postmeta.

  3. First of all, you can put stuff into captions like that:

    [caption ...]
      <a ...> ... </a>
      Your caption text
    [/caption]
    

    This works with most formatting HTML. It fails (iirc) for links, and it also might not place the caption exactly the way you like it.

    I have observed that stuff produced by shortcodes in captions is not sanitised, though. Therefore, my workaround uses the excellent and ever useful plugin Shortcode Exec PHP and create a shortcode captiontext with this PHP:

    return '<div style="text-align: center; margin: 5px 0px -20px 0px;">'.do_shortcode($content).'</div>';
    

    Adjust styling information to your liking, obviously. Now you can use it like this

    [caption ...]
      <a ...> ... </a>
      [captiontext]Your caption text[/captiontext]
    [/caption]
    

    and you can use all the HTML you want.

    Edit: Advantages of this solution: It is (relatively) stable against future changes in WordPress and your taste. As long as shortcodes are handled the way they are now, you can adjust your shortcode definition to compensate whatever changes in all posts ever written without having to touch every single one of them. Furthermore, the workaround is nicely integrated into WordPress’ natural flow; in particular, you can use other shortcodes in your caption. Last but not least, you do not have to touch any theme or core file for the workaround but use a mature plugin instead.