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?
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.
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.