This is a slightly technical post for WordPress developers.
If you are a developer trying to figure out how to filter and replace recurring HTML content from the WordPress loop by applying a filter to “the_content” then this post is for you!
If not, well, feel free to browse some of our other blog posts not related to WordPress!
Filtering And Replacing HTML In The WordPress Content Loop
The other day I had a requirement to replace a certain recurring HTML element on about 300 posts that had slight internal variations (in this case pricing) that were not fed by a shortcode and not built from Woo Commerce.
I tried to search the web for some posts on how to grab the WordPress content loop, do a REGEX find/replace dynamically, and then put that modified content back on the web.
I could not find a single post in the top 30 results about this specific approach, which is why I am writing this if you’re in the same situation as I was!
Your first question might be, why not just use a find/replace method one time on the posts?
Good question! Our requirement from the client was to make these changes reversible after a 30 day testing period.
They also didn’t want to change ALL the posts, but leave a special category that would be ‘untouched’ by the REGEX filter.
In this case, they wanted to have ‘call only’ pricing on some real-estate type posts, while others still showing the original pricing painstakingly put on there by some poor web developer last month.
By changing the content via a WordPress filter applied to the “the_content” in the loop, our changes don’t affect the original stored post content, and can be reversed by simply disabling the WordPress filter in the functions.php file.
The WordPress Functions Code To Filter And Replace HTML In “The_Content”
function change_pricing($content) { if( (is_singular()) && (is_main_query()) && (!in_category('special-deals')) ) { $string = $content; $pattern = '#<li> Price:(.*?)</li\b[^>]*>#s'; $replacement = '<li> Call For Price: <a href="tel:5558885555">555-888-5555</a></li>'; $content = preg_replace($pattern, $replacement, $string); } return $content; } add_filter('the_content', 'change_pricing');
This WordPress Filter Code Explained
First, you need to put this in your functions.php file. It will not really work anywhere else.
Second, this code has two parts. The first part is the actual function, and the second part is the ‘call’ to that function from the WordPress filter method.
For our function, we open it like this:
function change_pricing($content) {
You don’t have to keep the same function name of “change_pricing” but should keep “$content” in there if following this example.
Next, we are running three conditionals:
if( (is_singular()) && (is_main_query()) && (!in_category('special-deals')) ) {
This lets us control when the filter runs. In this case, we are only running it on single post pages, within the main query loop, and NOT for posts in the certain category of “Special Deals” which we identify by the category slug.
Next, we want to do the actual PHP code that lets us run a REGEX (regular expression) and find/replace our targeted HTML.
//we want the $string variable to take all the html on from our $content variable; $string = $content; //now we need to set the pattern we are looking for that we want to replace in the loop content; $pattern = '#<li> Price:(.*?)</li\b[^>]*>#s'; //now we need to decide what to replace that pattern match with; $replacement = '<li> Call For Price: <a href="tel:5558885555">555-888-5555</a></li>'; //finally we will run the PHP preg_replace function and capture the results in the $content variable; $content = preg_replace($pattern, $replacement, $string);
The inline notes should explain most of this. For your own examples, you will want to change the $pattern and $replacement variables to whatever you are trying to actually find/replace.
The trickiest part for you will probably be finding a REGEX that works for the $pattern you want to find.
The PHP.net manual has documentation on this specific function we are using, and on REGEX also.
When you set your $replacement variable you don’t need REGEX, you can just put the plain HTML that you want to put in place of the targeted HTML you found.
Finally, we need to return the $content variable for WordPress and close the brackets on our function:
} return $content; }
For the second part where you are now ‘calling’ the function to your filter, any function you make like this has to be added with:
add_filter('the_content', 'your_cool_function_name_here');
That tells WordPress to run your function as a filter on the “the_content” output for any loop with it.
You can find out more about WordPress filters on their codex site too.
Save this to your functions.php file in the active theme folder for your WordPress site, and when you load the individual posts in your targeted WordPress categories you should see instant filtering going on!
If you have WP Super Cache or other caches running, make sure to clear those first. Since this works via PHP it won’t run if the page is already cached.
Hope this helps some other WordPress developer in the same situation that we were in! Let us know if you have questions or how it is working for you in the comments below.