Wordpress - Stop Wordpress Wrapping Images In A "P" Tag

here's what we did yesterday on a client site that we were having this exact problem with... I created a quick filter as a plugin and activated it.

<?php
/*
Plugin Name: Image P tag remover
Description: Plugin to remove p tags from around images in content outputting, after WP autop filter has added them. (oh the irony)
Version: 1.0
Author: Fublo Ltd
Author URI: http://fublo.net/
*/

function filter_ptags_on_images($content)
{
    // do a regular expression replace...
    // find all p tags that have just
    // <p>maybe some white space<img all stuff up to /> then maybe whitespace </p>
    // replace it with just the image tag...
    return preg_replace('/<p>(\s*)(<img .* \/>)(\s*)<\/p>/iU', '\2', $content);
}

// we want it to be run after the autop stuff... 10 is default.
add_filter('the_content', 'filter_ptags_on_images');

If you drop that into a php file in your /wp-content/plugins folder and then activate it, it should remove the p tags from any para that just contains an image.

I'm not sure how strong the regexp is in terms of if it will fail with outputs from other editors - for example if the img tag is closed with just > it will fail. If anyone has anything stronger, that would be really helpful.

Cheers,

James

--- Improved filter ---

To work with images that are wrapped in links, it keeps the links in the output and removes the p tags.

return preg_replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);

Basically you need to make WordPress treat img like block-level element for the purpose of formatting. Such elements are hardcoded in wpautop() and list is unfortunately not filtered.

What I would do is:

  1. Fork wpautop() under different name.
  2. Add img to regexp in $allblocks variable.
  3. Remove wpautop from the_content filter.
  4. Add your forked version to the_content.
  5. You might need to play with priority and possibly remove and re-add other filters if something breaks because of changed processing order.

maybe this will help

remove_filter('the_content', 'wpautop')

But then you are going to add the paragraphs for everything else manually.