How to stop WordPress wrapping images in P tags

Wordpress has a genius and at the same time annoying feature that automatically wraps inline elements in “P” tags for you. The nerd that wrote the function “wpautop” forgot to provide us an option to populate the array of defined block level elements in-case we wanted an image or perhaps even a span tag treated as a block level element and not wrapped in a P tag automatically.

After much research and not find a single straight forward answer that worked, I devised my own little solution. Basically what we have to do is create a new function called “wpautop_forked” inside of your theme functions.php file and then remove the annoying wpautop filter function and specifying our own instead. Here is the code below, function taken from the wp-includes file formatting.php for the latest version of WordPress at the time of writing 3.0.4. View the file and function on WordPress Trac here.

As you will see below all I did was add img to the faux array inside of the variable $allblocks. You can now make other inline elements be treated as block by WordPress as well by adding them with a pipe separator into the variable. The best part of about this approach is that we’re not hacking core files and I don’t think the wpautop function hardly ever gets changed. Dear WordPress development team nerds, fix this blatantly obvious issue. If I don’t want to abide by web standards to make complicated layouts a little easier, let me.


function wpautop_forked($pee, $br = 1) {</code>

if ( trim($pee) === '' )
return '';
$pee = $pee . "\n"; // just to make things a little easier, pad the end
$pee = preg_replace('|
\s*
|', "\n\n", $pee);
// Space things out a little
$allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li
|pre|select|option|form|map|area|blockquote|img|address|math|style|input
|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer
|nav|figure|figcaption|details|menu|summary)';
$pee = preg_replace('!(]*&gt;)!', "\n$1", $pee);
$pee = preg_replace('!()!', "$1\n\n", $pee);
$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
if ( strpos($pee, ' $pee = preg_replace('|\s*]*)&gt;\s*|', "", $pee); // no pee inside object/embed
$pee = preg_replace('|\s*\s*|', '', $pee);
}
$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
// make paragraphs, including one at the end
$pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
$pee = '';
foreach ( $pees as $tinkle )
$pee .= '

' . trim($tinkle, "\n") . "

\n";
$pee = preg_replace('|

\s*

|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
$pee = preg_replace('!

([^&lt;]+)!', "

$1

", $pee);
$pee = preg_replace('!

\s*(]*&gt;)\s*

!', "$1", $pee); // don't pee all over a tag
$pee = preg_replace("|

( &lt;li.+?)

|", "$1", $pee); // problem with nested lists
$pee = preg_replace('|
]*)&gt;|i', "

", $pee);
$pee = str_replace('

', '

', $pee);
$pee = preg_replace('!

\s*(]*&gt;)!', "$1", $pee);
$pee = preg_replace('!(]*&gt;)\s*

!', "$1", $pee);
if ($br) {
$pee = preg_replace_callback('/&lt;(script|style).*?&lt;\/\\1&gt;/s', create_function('$matches', 'return str_replace("\n", " ", $matches[0]);'), $pee);
$pee = preg_replace('|(?&lt;!
)\s*\n|', "
\n", $pee); // optionally make line breaks
$pee = str_replace(' ', "\n", $pee);
}
$pee = preg_replace('!(]*&gt;)\s*
!', "$1", $pee);
$pee = preg_replace('!
(\s*]*&gt;)!', '$1', $pee);
if (strpos($pee, ']*&gt;)(.*?)

!is', 'clean_pre', $pee );
$pee = preg_replace( "|\n

$|", '

', $pee );

return $pee;
}

remove_filter('the_content', 'wpautop');
add_filter('the_content', 'wpautop_forked');

Also read...

Comments

  1. great fix! I’ve always found that extremely annoying when making themes. Sometimes had to use custom fields for images but this function works great so far. Thanks a million

  2. This is a life-saver. I make a good bit of my living doing wordpress work, and autop is very much my least favorite aspect of the platform.

  3. Calvin,

    To be fair though I think the same solution exists in many forms and I probably took inspiration from elsewhere too. Not to mention it’s not exactly a unique idea forking a function and adding the image in to the array of block elements. Lots of people have come up with the same method and haven’t bothered to publish the results.

  4. Totally copied that from the other person’s site. Even the bloody comments are copied…inspiration….my butthole

  5. Yo James,

    Look at the publish dates, he posted June, 2011 – I posted January, 2011. I posted before him. And for your information, want to know why the code is exactly the same including comments? Because all I did was modify pre-existing code, all I added as img to the display block array, the rest of the code is from the WordPress core itself. So of course the code is the same, the other guy didn’t write it either. We both have the same solution, and it’s a really simple solution.

    If you bothered to read my article correctly, you would see I link to the WordPress Trac and particular file where the function and code exists: core.trac.wordpress.org/browser/tags/3.0.4/wp-includes/formatting.php#L188 – do the comments in that code look familiar?

    So nice one, you’re the asshole in this situation. I suggest you go back to playing World of Warcraft and beating off into that old crusty sock of yours.

  6. Thank you SO much for posting this. This issue had been driving me crazy, plug ins and other solutions posted elsewhere did nothing at all. This is the only thing that seemed to do the trick… I’m a happy woman again! lol

  7. Thank you for posting this solution in a clear, coherent manner. I’m a PHP and WP newb, so this was exactly what I needed.

    :)

  8. Thanks for stopping by Adam, no worries. I think people jump to conclusions far too easily sometimes. The simpler solution you posted indeed is better, it’s a whole two million lines shorter than forking the internal function and adding the image tag to the block of. Got to love regular expressions, so powerful and yet so complicated.

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>

Notify me of followup comments via e-mail. You can also subscribe without commenting.