4

I've searched Google and can find no mention of how to change Wordpress image captions to wrap the caption in a H2 or H3.

How do we wrap image captions inside H2, H3 tags?

Thanks.

  • Is this just for HTML in general or is this WordPress related? – Andy Macaulay-Brook Jul 27 '16 at 10:39
  • 3
    The captions generated through TinyMCE are shortcodes. You've got a nice example on how to manipulate its html in the Codex page for the filter img_caption_shortcode. – Luis Sanz Jul 27 '16 at 11:00
  • 1
    @LuisSanz I was going to answer and paste in a variation from the codex page. While this is the way to do it, you probably want to make sure that you are using the most recent version of the caption HTML by checking WP source and also respecting the theme's HTML5 settings. Code pasted in an answer here is considered better than a link that might whither in the future. – Andy Macaulay-Brook Jul 27 '16 at 11:26
  • 1
    @AndyMacaulay-Brook, I am aware of both things. :) Your first point explains precisely why I don't like answering with a copy-paste without checking against WP source files and testing the code myself. I just didn't have the time to write an in-depth answer and its explanation, but I thought the OP would appreciate a clue until other user or myself -in a few hours- could ellaborate further. Are links in comments in WPSE a bad practice? – Luis Sanz Jul 27 '16 at 12:29
  • 1
    I think we have the same approach :-) I don't know the general rule, but if a link in a comment gets the OP fast help and the OP pastes their answer later, or someone else uses the link to answer, then I think links in comments are helpful. One goal is to help the OP to help themselves quickly, another is to make the Q&A self-contained with a long lifetime. – Andy Macaulay-Brook Jul 27 '16 at 12:31
4

You can hook into the filter img_caption_shortcode and replace the whole captioned image. Here I've copied the caption shortcode function from WP4.5, left the version used if your theme declares HTML5 support as it is (using figcaption) and modified the non-HTML5 version to use h2.

function wpse_233354_img_caption_shortcode( $empty, $attr, $content = null ) {
    // New-style shortcode with the caption inside the shortcode with the link and image tags.
    if ( ! isset( $attr['caption'] ) ) {
        if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
            $content = $matches[1];
            $attr['caption'] = trim( $matches[2] );
        }
    } elseif ( strpos( $attr['caption'], '<' ) !== false ) {
        $attr['caption'] = wp_kses( $attr['caption'], 'post' );
    }

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

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

    if ( ! empty( $atts['id'] ) )
        $atts['id'] = 'id="' . esc_attr( sanitize_html_class( $atts['id'] ) ) . '" ';

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

    $html5 = current_theme_supports( 'html5', 'caption' );
    // HTML5 captions never added the extra 10px to the image width
    $width = $html5 ? $atts['width'] : ( 10 + $atts['width'] );

    /**
     * Filter the width of an image's caption.
     *
     * By default, the caption is 10 pixels greater than the width of the image,
     * to prevent post content from running up against a floated image.
     *
     * @since 3.7.0
     *
     * @see img_caption_shortcode()
     *
     * @param int    $width    Width of the caption in pixels. To remove this inline style,
     *                         return zero.
     * @param array  $atts     Attributes of the caption shortcode.
     * @param string $content  The image element, possibly wrapped in a hyperlink.
     */
    $caption_width = apply_filters( 'img_caption_shortcode_width', $width, $atts, $content );

    $style = '';
    if ( $caption_width )
        $style = 'style="width: ' . (int) $caption_width . 'px" ';

    $html = '';
    if ( $html5 ) {
        $html = '<figure ' . $atts['id'] . $style . 'class="' . esc_attr( $class ) . '">'
        . do_shortcode( $content ) . '<figcaption class="wp-caption-text">' . $atts['caption'] . '</figcaption></figure>';
    } else {
        $html = '<div ' . $atts['id'] . $style . 'class="' . esc_attr( $class ) . '">'
        . do_shortcode( $content ) . '<h2 class="wp-caption-text">' . $atts['caption'] . '</h2></div>';
    }

    return $html;
}

add_filter( 'img_caption_shortcode', 'wpse_233354_img_caption_shortcode', 10, 3 );
0

In WordPress you can modify the HTML output of the [caption] shortcode using a custom filter on the img_caption_shortcode hook. You can change things however you want. The filter should return a string containing the full HTML code that should be displayed.

In the codex you have a full example of how to modify it.

add_filter( 'img_caption_shortcode', 'wpse_233363_img_caption_shortcode', 10, 3 );

function wpse_233363_img_caption_shortcode( $empty, $attr, $content ){
    $attr = shortcode_atts( array(
        'id'      => '',
        'align'   => 'alignnone',
        'width'   => '',
        'caption' => ''
    ), $attr );

    if ( 1 > (int) $attr['width'] || empty( $attr['caption'] ) ) {
        return '';
    }

    if ( $attr['id'] ) {
        $attr['id'] = 'id="' . esc_attr( $attr['id'] ) . '" ';
    }

    return '<div ' . $attr['id']
    . '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>';

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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