Remove and replace p tag image wp

remove p images wp

WordPress automatically wraps an image in a p tag but what if you don’t want this?

A long time ago I found a snippet on the web removing and replacing the “p” tag around the image.
It seems to work OK until I start using caption which resulted in the template being ripped apart. What happen was (tested on Twenty Seventeen wp 4.9.2) that the sidebar which is standard inside the ” div wrap” class (which holds the content) moved all the way down just before the footer. This was caused by the “figure” tag which automatically replaces the “p” tag when you write a caption. Removing the snippet was not an option ’cause I needed to wrap the images in a div for the layout I was making. Removing the autowp was also no option as I needed the “p” tag to appear automatically in the editor. Completely removing the figure tab resulted in unwanted formatting as the caption wasn’t wrapped in anything. After a long search which nearly make it seem impossible I finally found this post written by Micah Miller-Eshleman which works even if I use the caption. When you use the caption the formally now “div” tag is replaced by the figure tag, which is fine in this case. I could have just replaced all the “p” tags by the figure tag but then one would end up using the figure tag in places it’s not meant for.

I tweaked the code a little in order to have a “div” tag around the image, so I replaced this line of code

return $image . $content;

with this line

return '<div  class="divphoto">'. $image .'</div>'. $content;

The orginal snippet can be find here

/**
 * Move image inside <p> tag above the <p> tag while preserving any link around image.
 * Can be prevented by adding any attribute or whitespace to <p> tag, e.g. <p class="yolo"> or even <p >
 */
function gc_remove_p_tags_around_images($content)
{
	$contentWithFixedPTags =  preg_replace_callback('/<p>((?:.(?!p>))*?)(<a[^>]*>)?\s*(<img[^>]+>)(<\/a>)?(.*?)<\/p>/is', function($matches) 
	{
		/*
		Groups 	Regex 			Description
			<p>			starting <p> tag
		1	((?:.(?!p>))*?)		match 0 or more of anything not followed by p>
			    .(?!p>) 		anything that's not followed by p>
			  ?: 			non-capturing group. 
				    *?		match the ". modified by p> condition" expression non-greedily
		2	(<a[^>]*>)?		starting <a> tag (optional)
			\s*			white space (optional)
		3	(<img[^>]+>)		<img> tag
			\s*			white space (optional)
		4	(<\/a>)? 		ending </a> tag (optional)
		5	(.*?)<\/p>		everything up to the final </p>
			i modifier 		case insensitive
			s modifier		allows . to match multiple lines (important for 1st and 5th group)
		*/
			
		// image and (optional) link: <a ...><img ...></a>
		$image = $matches[2] . $matches[3] . $matches[4];
		// content before and after image. wrap in <p> unless it's empty
		$content = trim( $matches[1] . $matches[5] );
		if ($content) {
			$content = '<p>'. $content .'</p>';
		}
		return '<div  class="divphoto">'. $image .'</div>'. $content;
	}, $content);
	
	// On large strings, this regular expression fails to execute, returning NULL
	return is_null($contentWithFixedPTags) ? $content : $contentWithFixedPTags;
}
add_filter('the_content', 'gc_remove_p_tags_around_images');

Leave a Reply