Shortcode & Autop

I have a little WordPress plugin I use on some of my sites and it employs shortcodes. The shortcodes are not self-closing and they are wrapped in more shortcodes. They’re nested shortcodes. Using them looks like this:

[ltabjes talen="Taal Language"][ltab taal="Taal"]

Content

[/ltab][ltab taal="Language"]

More content

[/ltab][/ltabjes]

WordPress wraps p-tags around each of these shortcode tags, and adds more p-tags inside the shortcodes, adding more space than is wanted. All those empty p-tags are a drag. The shortcode_unautop function removes the outer paragraph tags, but not the inner ones. I don’t want to remove wpautop altogether because the content in the shortcode might still need it. How to solve this?

EDIT! Don’t do this first solution: It targets all content instead of just the content inside the shortcode–which is what you want. Not only bad practice, but it could seriously mess up the rest of your site’s content as well, paragraph tags are added in odd places.

Solution 1

What: Basically, removing wpautop and then adding it again with a lower priority, so it gets executed after the shortcode has been executed, and adding shortcode_unautop just to be save.

//move wpautop filter to AFTER shortcode is processed
remove_filter( 'the_content', 'wpautop' );
add_filter( 'the_content', 'wpautop' , 99);
add_filter( 'the_content', 'shortcode_unautop',100 );

Where:Stack Overflow by helgatheviking and confirmed by Matthew Blackford – it’s old but good. and terrible

Notes: It helps if users keep the shortcodes on their own lines, as in the example above, but it doesn’t break functionality or look bad if they were to put everything on one line either.

EDIT! Do this instead:

Solution 2

What: A general function that replaces paragraphs with a new-line escape character, removes br-tags and then reapplies filters, so you’ll keep formatting. You then call that general function inside your shortcode so it only gets applied to your shortcode. Beautiful.

/*
 * The shortcode, any that filters complex content
 */
    function my_custom_shortcode( $atts, $content = "") {
        $content = custom_filter_shortcode_text($content);
        return '<div class="looks-different">'. $content .'</div>';
    }
    add_shortcode( "altered_content", "my_custom_shortcode" );


/*
 * Utility function to deal with the way 
 * WordPress auto formats text in a shortcode.
 */
    function custom_filter_shortcode_text($text = "") {
        // Replace all the poorly formatted P tags that WP adds by default.
        $tags = array("<p>", "</p>");
        $text = str_replace($tags, "\n", $text);

        // Remove any BR tags
        $tags = array("<br>", "<br/>", "<br />");
        $text = str_replace($tags, "", $text);

        // Add back in the P and BR tags again, remove empty ones
        return apply_filters("the_content", $text);
    }

Where: Stack Overflow by Drew Baker

Notes: This works beautifully on the extra paragraphs inside shortcodes. Users can keep shortcodes on the same line as the content or not, doesn’t matter.

EDIT: Gutenberg Note: if you find that this removes more <br> tags than you want when using the Gutenberg editor, comment out the two lines directly below // Remove any BR tags.


Photo by Kimo Kremer on Unsplash

4 thoughts on “Shortcode & Autop”

  1. Normally, I hate giving out my details to post comments on blogs. But after spending 4 hours on this stupid wpautop problem and being so close to pulling all of my hair out, I decided I should write. You might have saved my life. I might even owe my firstborn to you.
    I have done EVERYTHING I possibly could try and was feeling so frustrated before trying your solution. I must have visited 50 sites to find the answer.

    P.S. Please excuse my emotional outburst. It’s difficult to reign in my emotions at this point. The “Solution 2” works.

    Reply

Leave a Comment