The <br>
tag is coming from wpautop()
, which is one of a number of display filters added to the content via wp-includes/default-filters.php
:
// Display filters
add_filter( 'the_content', 'wptexturize' );
add_filter( 'the_content', 'convert_smilies', 20 );
add_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'shortcode_unautop' );
add_filter( 'the_content', 'prepend_attachment' );
add_filter( 'the_content', 'wp_make_content_images_responsive' );
...
// Shortcodes
add_filter( 'the_content', 'do_shortcode', 11 ); // AFTER wpautop()
WordPress runs the do_shortcode
filter after wpautop
has has already been run on the content.
Here's a function that will remove the <br>
tag (source):
function shortcode_wpautop_fix( $content ) {
// Define your shortcodes to filter, '' filters all shortcodes
$shortcodes = array( '' );
foreach ( $shortcodes as $shortcode ) {
$array = array (
'<p>[' . $shortcode => '[' .$shortcode,
'<p>[/' . $shortcode => '[/' .$shortcode,
$shortcode . ']</p>' => $shortcode . ']',
$shortcode . ']<br />' => $shortcode . ']'
);
$content = strtr( $content, $array );
}
return $content;
}
add_filter( 'the_content', 'shortcode_wpautop_fix' );
An alternative approach is to ensure that do_shortcode
is applied before wpautop
. This can be accomplished by changing the priority of the display filters.
remove_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'wpautop', 99 );
add_filter( 'the_content', 'shortcode_unautop', 100 );
Note that do_shortcode
is already run at priority 11, so the goal of running it before wpautop
is accomplished with the code immediately above.
Also worth noting, shortcode_unautop
deals specifically with the markup on the outside of the shortcode, not the inside.