Whenever you’re building custom solutions for other people, you may find yourself having to deal with nuanced cases of how WordPress is rendering the content.
This usually comes down to the theme, at least one plugin, or the combination of both. And if you need to work with images individually, then it can be a bit of a challenge. The problem with even trying to write a post like this is that it’s hard even to describe a situation in which you may need something like this.
Even still, I’m going to do the best I can. That is, I want to share how to modify image containers on the server-side before rendering them on the client-side and do so using PHP’s DOMDocument library.
Sound like a lot? Hopefully, I can break this down easily enough.
Modify Image Containers on the Server-Side
Before getting into the code, let’s say you have a them that renders images in a single paragraph element (or any type of block-level element) and you need to wrap each element in some type of class so that you’re able to access it via CSS or JavaScript.
Where We Are
So, for starters, let’s say the images render like this:
And you need to render them like this:
Now, you may or may not need space between them. It doesn’t really matter because you have control over this via CSS. But you do have control over how this is sent across the wire to the client-side.
To do this, you need a few things:
- Access to PHP’s DOMDocument library,
- Understanding of how to manipulate content via WordPress’ the_content hook,
- A strategy for how you want to wrap the images.
I’ll walk through each of these in the code but suffice it to say that I’m going to wrap each image in a paragraph element. You can obviously opt to do whatever it is you’d like.
How To Do It
First, make sure that you’ve declared you’re using the content of the DOM document above your class:
Next, go ahead and create a hook to the_content. How you do this will depend on how you’ve organized your code (be it OOP or not). For this example, I’m going to show a very simple example of how to do it:
After that, you’ll need to do a little bit of work (all of which is below but outside the scope of this post). This includes:
- converting the encoding of the HTML entities,
- creating an instance of the DOM document,
- loading the HTML of the post from the incoming content
In the code, it should look like this:
Next, you need to iterate through the img elements and make sure that you’re setting a proper attribute. You may opt to use a class, you may opt to use a data attribute, or you may opt to use something else. This part doesn’t matter.
Note that for a given image, you’ll want to check that the next element is not a paragraph element since that’s what I’m opting to wrap the image. In other words, if the next element is not a paragraph, then we’ll wrap the element in a paragraph element.
To do this, the skeleton of the main function should look like this:
Then the function responsible for actually wrapping the element in a paragraph element should look like this:
Be sure to read the DocBlock of the code to understand how the function works. Simply put:
- it accepts an instance of the document and the image element,
- creates a paragraph element,
- adds a class attribute
- replaces the original image element with the paragraph,
- and adds the image as a child element
And since we’ve based the document object into the method, we don’t have to return anything.
The final version of the original function should look like this:
And your output should look like the image above. Remember, though; you’ve got to return the results of the document instance to WordPress, so it properly renders the HTML. And that’s what the saveHTML function is doing in the code above.