When adding an image to a page or post, WordPress is automatically adding a paragraph tag <p>
as parent holding the image. Like so:
<p><img src="my-image.jpg" alt=""></p>
Since there is no parent selector in CSS I’d love to find a solution to apply a specific classname to those paragraphs holding an actual image. The example above would thus result in:
<p class="my-class"><img src="my-image.jpg" alt=""></p>
Any idea if I can use add_filter()
to apply a classname to each p
that holds an image?
You could use jQuery if you don’t mind to rely on JavaScript for adding the class.
Update: the
.has()
method is probably faster, see this jsperf.com test.If you need this to be a PHP solution. You could do something like this using ‘the_content’ filter. This will add the class name “content-img-wrap” to any paragraph that wraps only an image tag when WordPress prints your post content. So this will not wrap a paragraph with an image and a span. See update if that is what your looking for.
** UPDATE BELOW: In response to the need for a more flexible wrap. I created and quickly tested this regex against 3 automatically wrapped paragraphs (meaning I didn’t add the p tags, WP did) with images at the end of a post. They each also contained some random tags and carriage returns for testing likely cases and flexibility. The idea is that you don’t have to match anything after the <img> because the presence of any <img> proves our case. Then we just add our custom class/es in (improvements more then welcome):
While I understand wanting the front end to be as lean as possible and therefore stating you want a PHP solution…
which I have not tested)
this… further reading (follow its links) at
https://stackoverflow.com/questions/18664997/how-can-i-use-regular-expression-to-grab-an-img-tag#comment27488762_18664997
Personally, I spent quite a bit of time on this just for fun, and I kept coming up with ways to break the regex matching (hence, why not to use PHP without a library add-on specifically designed to traverse HTML, as mentioned in the link above)…
For example:
This screenshot’s rule will match
<p>
or even<P >
(the simplest match, not trying yet for P tags that already have a class or have other attributes but not a class), but see that it has to be matched WITHIN the entire block of closing tags (where PHP regex for HTML falls apart at the seams)… the arrow points to where a closing P tag and opening P tag are on the same line and therefore if you were to count this as a FIND and then replace the<p
with<p class="my-class"
, you’d be addingmy-class
to the wrong paragraph.If you didn’t want such an “every scenario” use case, it’s doable via regex. If you narrow your scope a bit.
If you decide to limit your scope, you might be interested in this information:
Here’s some starting code if you do force yourself down this complicated route (instead of via jQuery):
Note the use of http://codex.wordpress.org/Function_Reference/force_balance_tags
By default, it gets used on the Excerpt and Comments
If you look at its source, it actually uses REGEX: https://core.trac.wordpress.org/browser/tags/4.1/src/wp-includes/formatting.php#L1453
SIDENOTE
I assume the reason they fallback (not ideal) to using REGEX is because of WP’s need to run on almost any host’s PHP configuration imaginable (i.e. not wanting to load a library in case that PHP extension is disabled). You could choose to load a PHP library designed to do this in your own solution.
/SIDENOTE
It’s a whole lot of code to be ran every time
is_singular()
. As such, I’m not sure it’d be worth it to use as inspiration for some complex PHP solution when your site is likely already using JS/jQuery.Please share your thoughts.
WordPress uses the
autop
function to add<p></p>
to line breaks in your content.The autop function can be found on line 373 in formatting.php. An option is to disable the default autop (see below), create a new version of the function adding your class, and then apply it to your content (see the link below for that too). I guess you’d be adding a regex around line 442 to do that.
If you just want to remove the effect of the paragraph you can disable
autop
like this:Which can be found on the autop page: