I’m using a basic shortcode to wrap some text in an expandable div. What appears to be happening is that the wpautop is inserting a stray closing paragraph tag at the beginning and a stray opening paragraph tag at the end of the content being wrapped.

Here’s how it looks in the editor:

[expandable text=”Show Content”]

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras
fermentum facilisis malesuada. Suspendisse potenti. Aenean dui turpis,
ornare in ipsum eget, vestibulum egestas nulla.

[/expandable]

And the rendered HTML:

<div class="expandable"><a href="#" class="expand-link">Show Content</a></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras fermentum facilisis malesuada. Suspendisse potenti. Aenean dui turpis, ornare in ipsum eget, vestibulum egestas nulla.</p>
<p></div>

This is the shortcode function:

function expandable_content_shortcode( $atts, $content = null ) {
    $args = shortcode_atts( array(
        'text' => __( 'View More', $this->plugin_slug ),
        'linklocation' => 'top'
    ), $atts, 'expandable' );

    if ( $args['linklocation'] === 'top' ) {
        $output="<div class="expandable-content"><a href="#" class="expand-link">" . $args['text'] . '</a>' . $content . '</div>';
    } else {
        $output="<div class="expandable-content">" . $content . '<a href="#" class="expand-link">' . $args['text'] . '</a></div>';
    }

    return $output;
}

2 Answers
2

This is frustrating issue as I can’t depend on the content editors to be savvy enough with WordPress / HTML to understand how the text they input will be parsed…

–EDIT–

Having thought of this a bit more I have reconsidered my earlier answer. HTML5+ comes with the Tidy extension, if you are able to use this on your server then the following will work:

function cleanUpAutoP($content)
    {
        $tidy = new Tidy();
        // Switch out the encoding an doctype in $tidyArgs to suit your use case
        // 'show-body-only' HTML to be parsed as a fragment
        // rather than a whole document
        $tidyArgs = array(  'doctype' => 'html',
                            'input-encoding' => 'utf8',
                            'output-encoding' => 'utf8',
                            'show-body-only' => true
                    );
        // Return the repaired string
        return $tidy->repairString($content, $tidyArgs);
    }

This way you can enjoy all the benefits of sweet, sweet P tags without the fear that wpautop will have messed something up. Further options for $tidyArgs can be seen in the documentation.

If Tidy is not available for whatever reason this should still work:

function cleanUpAutoP($content) {

    // Replace all OPENING paragraph tags with <br /><br />
    $content = preg_replace('/<p[^>]*>/', '<br /><br />', $content);

    // Remove all CLOSING p tags
    $content = str_replace('</p>', '', $content);


    return $content;
}

The obvious drawback of the latter method that I cannot apply styles to p tags in shortcodes, but until a better solution comes along, or the issue is fixed in WordPress, it will do!

Leave a Reply

Your email address will not be published. Required fields are marked *