How to Prevent the WPAutoP Filter in a Shortcode

As I was developing a simple shortcode the other day, I realized the output was being filtered by wpautop(), which adds <p></p> to the return code.

I finally found a snippet of code from BetterWP.net which solved exactly my problem.

The main issues was that the shortcode was being processed too late in the code, and I needed to run the shortcode before wpautop() ran.

Here’s the resolution:

Original Shortcode

function  wpfthemes($atts){
        extract( shortcode_atts( array(
        'value1' => '',
        'value2' => '',
        'value3' => 'default value',
        ), $atts ) );
        if ( !empty($value1) && !empty($value2) )
                { return '...code...'; }
}

add_shortcode('wpfthemes','wpfthemes');

Code that Prevents wpautop()

function  wpfthemes($atts){
        extract( shortcode_atts( array(
        'value1' => '',
        'value2' => '',
        'value3' => 'default value',
        ), $atts ) );
        if ( !empty($value1) && !empty($value2) )
                { return '...code...'; }
}

function pre_process_shortcode($content) {
    global $shortcode_tags;

    // Backup current registered shortcodes and clear them all out
    $orig_shortcode_tags = $shortcode_tags;
    $shortcode_tags = array();

        add_shortcode("wpfthemes","wpfthemes");

    // Do the shortcode (only the one above is registered)
    $content = do_shortcode($content);

    // Put the original shortcodes back
    $shortcode_tags = $orig_shortcode_tags;

    return $content;
}

add_filter('the_content', 'pre_process_shortcode', 7);

You’ll notice how in the second chunk of code, it puts the add_shortcode() inside the pre_ function that gets filtered at a lower priority. This is what prevents wpautop() from being applied to the output.

Hat tip to BetterWP for publishing this code.

UPDATE: After further review and an informative comment below by Carl, the result is that by default, WordPress does not apply the wpautop() function to shortcodes — which is correct, because it shouldn’t. But rather, because I have WP Unformatted by Alex King installed, it was causing all shortcodes to have wpautop() applied to them. Upon de-activating that plugin, the wpautop() disappears. As Carl mentioned though, some theme authors force WordPress to apply wpautop() before a shortcode is output, so this function still may come in handy for someone.

Comments

  1. By Carl Hancock on

    As I mentioned on Twitter, the behavior you are describing is not default WordPress behavior. By default, WordPress executes the wpautop() function BEFORE parsing shortcodes. Which means shortcode output should not be auto-formatted by the wpautop() function.

    However, many theme developers have implemented code in their themes that changes this default WordPress behavior unintentionally and it’s a negative side effect of code they have added to their theme that they think is a good feature.

    The typical cause of this is when WordPress theme developers include code such as this in their theme:

    http://www.wprecipes.com/disable-wordpress-automatic-formatting-on-posts-using-a-shortcode

    The “noformat” or “raw” shortcode functionality as it is typically referred to when a theme developer implements it. It varies. Some theme developers implement it with [noformat] as the shortcode name and others implement it exactly as it is in this wprecipes.com tutorial as the [raw] shortcode.

    Look at the code closely and you’ll see what it does and why it’s bad.

    In order to implement a shortcode that allows you to NOT auto-format a block of text in your post content, it changes the order in which WordPress processes content. It changes WordPress to process shortcodes BEFORE applying the auto-formatting. This results in ALL shortcode output being processed by the wpautop() function.

    We encounter this issue frequently while supporting Gravity Forms. When we see the Gravity Forms shortcode output has stray paragraph and break tags in the market that should not be there… we know right away that the site has this issue and it’s typically code in the theme. It’s possible it could be included in a plugin also, but we’ve only encountered it in themes.

    ThemeForest theme developers in particular seem to love adding this code to their themes.

    Reply »

    • By Jon on

      The problem is that when you add new lines inside your shortcode it still gets formatted. So, if you put a lot of content inside your shortcode you have to put it all one the same line. I guess that’s why themeforest authors often add it since it’s more user friendly.

      Reply »

  2. By Jonathan Dingman on

    You can put it into your functions.php file for your theme.

    Reply »

  3. By Thirdpotato on

    Thank you for the info. But now, it still doesn’t seem to have done anything. I’m seeming to have the problem particularly with content within shortcode, and h2 headers.
    I’ve used a text widget, and the text is set up to be h2. It works fine until I make something a hyperlink, afterwhich it adds an automatic linebreak. Is this the same problem?

    Reply »

    • By Jonathan Dingman on

      Sounds like your theme is adding some functions you may not want. Is your theme from a marketplace like Themeforest or Mojo?

      Reply »

  4. By Thom on

    After several days of searching for a solution to this, I’ve found a simple one that works flawlessly, and gives total control over its implementation. It’s a string replace applied only to defined attributes. I have it applied to an attribute called “message,” but it can also be applied to the content.

    $message = str_replace(“<br />”, “\n”, $message);
    $message = str_replace(“<br>”, “\n”, $message);
    $message = str_replace(“</p><p>”, “\n”, $message);

    Problem solved.

    Reply »

  5. By Thom on

    Well that stripped out the br and /p p tags when I posted the comment.

    Reply »

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>