21

I've seen the tutorials on creating a (raw) shortcode that leaves the code inside it untouched,

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

but unfortunately this only applies to one shortcode at a time... and because the else statement bypasses the normal filters and calls the functions directions. My other modifications to autop and texturize functions get ignored.

Is there a way to 1. match multiple shortcodes and 2. preserve my other add/remove filters to the_content?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
helgatheviking
  • 25,596
  • 11
  • 95
  • 152

4 Answers4

47

After implementing @helgatheviking's solution on multiple websites, I'm convinced that only these lines are required:

// 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);

Put them in your functions.php file and you're set.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matthew Blackford
  • 3,041
  • 1
  • 24
  • 28
  • 1
    Thanks for verifying that. I've accepted this answer so that people will stop using my full code. – helgatheviking Feb 04 '13 at 16:37
  • 1
    Where is shortcode_unautop defined? Is it a part of Wordpress? – Larry K Oct 25 '13 at 08:31
  • @LarryK it's in [wp-includes/formatting.php](https://core.trac.wordpress.org/browser/tags/3.8.3/src/wp-includes/formatting.php#L287) – Hobo Apr 15 '14 at 20:57
  • 1
    Seriously, why is this not the default? I was getting all sorts of weird mangled output from a shortcode that was run through wpautop twice— dropped this in and it's perfect. – Nate Beaty May 14 '15 at 22:19
  • 1
    @NateBeaty Just yet another weird quirk of WordPress I suppose. wpautop() is one of those functions that seem quite dated just in general, but these behaviours make it more than a little annoying. – InanisAtheos Mar 04 '16 at 13:33
  • 1
    Anybody remember in what part of functions.php? – Genaut May 10 '16 at 19:17
  • @user1422434 it would depend on your theme, because there's no standard structure for functions.php – Matthew Blackford May 11 '16 at 09:32
  • I have this configuration on all my pages, but now I moved one page to a different server and there's weird p tags in some shortcodes. Any ideas? :) – trainoasis Dec 13 '16 at 10:14
9

I solved this as best as possible by combining a slightly modified parse_shortcode_content function from Donal MacArthur (his originally manually calls wpautop... which I've removed. With the re-ordering of default filters to run wpautop much later... after the shortcode has already been processed instead of before.

// Clean up WordPress shortcode sormatting - important for nested shortcodes
// Adjusted from http://donalmacarthur.com/articles/cleaning-up-wordpress-shortcode-formatting/
function parse_shortcode_content( $content ) {

   /* Parse nested shortcodes and add formatting. */
    $content = trim( do_shortcode( shortcode_unautop( $content ) ) );

    /* Remove '' from the start of the string. */
    if ( substr( $content, 0, 4 ) == '' )
        $content = substr( $content, 4 );

    /* Remove '' from the end of the string. */
    if ( substr( $content, -3, 3 ) == '' )
        $content = substr( $content, 0, -3 );

    /* Remove any instances of ''. */
    $content = str_replace( array( '<p></p>' ), '', $content );
    $content = str_replace( array( '<p>  </p>' ), '', $content );

    return $content;
}

and moving the filters

// 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 );

EDIT:

The parse_shortcode_content() function is no longer required (if it ever was). Simply adjust the filter order.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
helgatheviking
  • 25,596
  • 11
  • 95
  • 152
  • with the filters re-ordered, i'm not even sure that i need to continue using the parse_shortcode_content( $content ) in lieu of simply do_shortcode($content) in my nested shortcodes – helgatheviking Jul 26 '11 at 17:22
  • thanks but where are you calling parse_shortcode_content? if i put that code in functions.php nothing happens. Thanks – Dominic Jun 01 '12 at 01:26
  • 1
    honestly, after a year, i can't really remember. i believe it was inside the shortcode function... in lieu of do_shortcode(). but try re-ordering the filters, that seemed to work for @dan – helgatheviking Jun 01 '12 at 02:22
  • This code doesn't look right. How can a 4-character long or 3-character long string ever be `''` (an empty string)? – Lèse majesté Sep 11 '12 at 18:31
  • i have no idea. it might not be right or even needed, anymore. – helgatheviking Sep 11 '12 at 18:39
5

In my case - this solution has broken one of the side shortcodes (revslider).

So I've found another solution here: http://wordpress-hackers.1065353.n5.nabble.com/shortcode-unautop-tp42085p42086.html

Which is to use another filter like this:

// Via http://www.wpexplorer.com/clean-up-wordpress-shortcode-formatting/
if ( !function_exists('wpex_fix_shortcodes') ) {
    function wpex_fix_shortcodes($content){
        $array = array (
            '<p>[' => '[',
            ']</p>' => ']',
            ']<br />' => ']'
        );
        $content = strtr($content, $array);
        return $content;
    }
    add_filter('the_content', 'wpex_fix_shortcodes');
}

It works fine for me :)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
chestozo
  • 1,203
  • 1
  • 12
  • 29
1

Please see my answer here:

Remove wpautop from shortcode content / remove whitespace in buffering

It allows you to turn off wpautop for as many specific shortcodes as you want using this:

include "shortcode-wpautop-control.php";
chiedolabs_shortcode_wpautop_control(array('shortcodeone', 'shortcodetwo'));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chiedo
  • 7,288
  • 3
  • 26
  • 22