2

We build a media (based on bootstrap 4 media object) shortcode with the following syntax:

[media img="https://via.placeholder.com/64x64.png"]<h5>List-based media object</h5>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus.[/media]

The function can be found here:

add_shortcode( 'media', 'xcore_shortcode_media' );
/**
 * Media shortcode
 *
 * @doc https://getbootstrap.com/docs/4.3/components/media-object/
 *
 * @param $atts
 * @param null $content
 *
 * @return string
 */
function xcore_shortcode_media( $atts, $content = null ) {
    extract(
        shortcode_atts(
            array(
                'style'         => 'primary',
                'class'         => '',
                'img'           => '',
                'align'         => '',
                'order'         => 'left'
            ),
            $atts
        )
    );

    // vars
    $style         = ( $atts['style'] ? $atts['style'] : 'primary' );
    $class         = ( $atts['class'] ? $atts['class'] : '' );
    $img           = ( $atts['img'] ? $atts['img'] : '' );
    $align         = ( $atts['align'] ? $atts['align'] : '' );
    $order         = ( $atts['order'] ? $atts['order'] : 'left' );

    $attributes = array(
        'class' => array( 'xcore-media', 'media' ),
    );

    if ( $style ) {
        $attributes['class'][] = 'media-' . $style;
    }

    if ( $class ) {
        $attributes['class'][] = $class;
    }

    if ( $img ) {
        $img_classes = array();

        if ( $order == 'left' ) {
            $img_classes[] = 'mr-3';
        } else {
            $img_classes[] = 'ml-3';
        }

        if ( $align ) {
            $img_classes[] = 'align-' . $align;
        }

        $img_html = '<img src="' . $img . '" class="' . implode ( ' ', $img_classes ) . '"/>';
    }

    $output = '<div ' . xcore_attribute_array_html( $attributes ) . '>';
        if ( $order == 'left' ) {
            $output .= $img_html;
        }

        $output .= '<div class="media-body">';
            $output .= do_shortcode( $content );
        $output .= '</div>';

        if ( $order == 'right' ) {
            $output .= $img_html;
        }
    $output .= '</div>';

    return $output;
}

The Problem:

WordPress puts an empty p-Tag right before the headline. When we start without a headline in our content, it works fine.

Here a example:

HTML code

Is there any way to remove this without deactivate the auto p function completely?

Thanks

2
  • What about having a custom shortcode attribute for the title and avoid writing HTML for it in the shortocde's content?
    – birgire
    Apr 15, 2019 at 16:46
  • Yes, this could be a fix for this case - but the autop is a general problem for shortcodes. :/
    – endcoreCL
    Apr 17, 2019 at 8:34

3 Answers 3

1

The empty p tag in the developer console means that you have other HTML being outputted inside it, which shouldn't be there. i.e the H5 tag for the heading.

This is because "do_shortcode" uses the wpautop filter which wraps everything in a p tag

Try remove the wpautop filter, run do_shortcode, and then re add the wpautop filter (otherwise any other shortcode outputs will run without it).

Replace

$output .= '<div class="media-body">';
    $output .= do_shortcode( $content );
$output .= '</div>';

With

$output .= '<div class="media-body">';
    remove_filter( 'the_content', 'wpautop' );
    $output .= do_shortcode( $content );
    add_filter( 'the_content', 'wpautop' );
$output .= '</div>';

You might need to add some p tags manually to your shortcode call.

[media img="https://via.placeholder.com/64x64.png"]<h5>List-based media object</h5><p>Cras sit amet nibh libero, in gravida nulla. Nulla vel metus scelerisque ante sollicitudin. Cras purus odio, vestibulum in vulputate at, tempus viverra turpis. Fusce condimentum nunc ac nisi vulputate fringilla. Donec lacinia congue felis in faucibus.</p>[/media]
1
  • Thanks i will give it a try.
    – endcoreCL
    Apr 17, 2019 at 8:35
-1

I've just had this problem myself, I found the solution using the PHP trim() function. You can use the second parameter to specify what to trim, in our case, we want to trim empty <p> tags, so this is (partly) the code I used;

function shortcodefunction($atts,$content) {
    $content = trim($content,'<p></p>');
    return $content;
}
add_shortcode('shortcode-name','shortcodefunction');
3
  • That is not exactly how trim() works. :) You don't have to list any character twice, like p, <` or >. And your function will trim a trailing p that isn't in a tag.
    – fuxia
    Aug 4, 2020 at 2:12
  • Ah, the solution worked well for me. And of course if you didnt want to get rid of trailing p tags, you could use ltrim instead of trim. Aug 5, 2020 at 6:23
  • I'm not talking about trailing p tags, but the letter p. The seconds argument to trim() ignores the order of the given characters.
    – fuxia
    Aug 5, 2020 at 10:03
-3

CSS :first-of-type selector will help to accomplish that:

.media-body p:first-of-type {
    display: none;
}
2
  • It would be nice to add a comment stating why downvoted. Apr 15, 2019 at 21:23
  • 1
    (The downvote does not come from me) - This is a solution... but not the greatest. The best way where to avoid empty p-tags in the code... :)
    – endcoreCL
    Apr 17, 2019 at 8:36

Your Answer

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

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