I am using WordPress as a CMS system, and I want to wrap every p
tag in some HTML I need for styling and positioning in my website.
I have found a piece of code that does this wonderfully for me, but it is overdoing it right now.
Here it is:
function tekst_wrapper($content) {
// match any p tags
$pattern = '~<p.*</p>~';
preg_match_all($pattern, $content, $matches);
foreach ($matches[0] as $match) {
// wrap matched p tag with div
$wrappedframe = '<div>' . $match . '</div>';
//replace original p tag with new in content
$content = preg_replace($pattern, $wrappedframe, $content);
}
return $content;
}
add_filter('the_content', 'tekst_wrapper');
This adds div tags around each p tag. But for every p tag there is in the post, it starts adding more div tags on each p tag. So say I have four p tags, the resulting HTML will be:
<div>
<div>
<div>
<div>
<p>random text</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<p>random text</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<p>random text</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<p>random text</p>
</div>
</div>
</div>
</div>
Obviously this not what I need, since I just want each p tag to be wrapped in a single div tag (or whatever my replacement HTML is going to be). Now my PHP skills aren’t that great, but I assume the foreach causes it to add div tags for every match it finds in the $matches
array? Is there any way to fix this?
You have several copies of the same <p> tag in your HTML and you are replacing every one of them on each iteration on your foreach loop. Use preg_replace or preg_replace_callback instead of foreaching.
Note that there is a question mark in the pattern, to make it lazy.
This would be expected because preg_match_all is matching all 4 of the p tags, then in the foreach, the preg_replace is replacing all 4 of the tags everytime the loop runs through, in total the loop runs 4 times and all tags are replaced 4 times resulting in the output above.
To resolve this simply use the preg_replace and abandon the preg_match_all, as preg_replace would replace it for all, so this is what you would end up with:
Ive update the regex to include ‘i’ at the end of it, which makes it case insensitive. This is because HTML is case insensitive.
Hope this helps.