I know: If you’ve been working with WordPress for any amount of time creating themes or plugins, then you’re probably familiar with filters. Even if you’re not really sure how they work, you’ve likely worked with something like the_content
.
And by that, you’ve likely written a line of code that looks like this:
It’s enough to work with, too. Usually, this is used whenever you want to modify the content before sending it to the browser to render.
But I recently had to work with it in a somewhat unusual way that required the usual of this filter, a template file, and PHP’s output buffer such that I was buffering WordPress content.
Buffering WordPress Content with Output Buffers
This is a bit of a lengthy post because I explain a bit of PHP’s output buffering, how it works, how to use it, and then I go on to explain why I used it in this project.
With that said, if you already know how it works, you can skip the next section. Then again, if you get all of this, then you likely know how all of this is going to pan out as it is, so this post isn’t for you 🙂.
That said, here’s what’s up:
- A short introduction to PHP’s output buffering system
- How this works in conjunction with WordPress hooks (and how I used it)
So skip around if needed. That said, here’s the gist of output buffering.
A Word About PHP’s Output Buffer
When working with PHP’s output buffer, there are a few concepts and functions that are worth understanding so the code makes sense.
This isn’t even a primer, but I want to make sure it’s clear as to what the functions do within the context of the code.
Output Buffering Defined
The concept of output buffering is pretty straightforward. From the PHP manual:
The Output Control functions allow you to control when output is sent from the script. This can be useful in several different situations, especially if you need to send headers to the browser after your script has begun outputting data.
In short, this gives us the control as to when data is actually sent to the browser versus having it done automatically.
Think of it this way: If you’ve ever used an include_once
statement to bring the contents of another script, then you’re having to execute the content of the script at runtime. Sometimes, though, you may want the script to execute but not output it’s content at that moment in the lifecycle.
This is where output buffering control comes into play.
Activate Output Buffering
To activate output buffering, we can make a call to ob_start
which, as the function name implies, starts output buffering. The manual is clear as to what this does (as one would hope it would be):
This function will turn output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer.
The key, in my opinion, in noting that the output is stored in an internal buffer. This means PHP will maintain whatever script is executed while output buffering is on within a mechanism it maintains versus sending it to a browser.
Retrieving Buffer Contents
Since we’re storing content in the output buffer, we eventually need to be able to retrieve it. To do this, we use ob_get_clean
which is a function that does the following:
Get current buffer contents and delete current output buffer
Easy enough to understand (I think), but how to we tie all of this together?
Using Buffering and WordPress Filters
So in the project, I needed to do the following:
- Grab all of the users under certain criteria for which I used WP_User_Query
- Make those users available to a partial that will render them (and perform some other actions on them)
- Append them to the content
- Return the content to WordPress for rendering.
The code looks like this:
But why did I have to place this into a buffer? Or, another way of asking is why couldn’t I just do an include_once
?
And that’s because the partial being included is performing some PHP operations of its own within its own context. So I need all of that information to be fully completed before adding it to a buffer and then rendering it with the rest of the content.
I’ll talk more about this later. But if you find yourself in a similar situation, the code for doing so is above.
A Better Architecture
To be honest, this particular solution may not be correct. Architecturally, I know there are alternative ways to handle templating, outputting content, and things like that.
But, as with many projects, there are constraints, previous implementations in the codebase, and so on, so this isn’t necessary meant to be a purist’s approach to handling this problem.
It’s more of a “here’s how I handled it given what I have and the requirements.” Either way, maybe this will help. Or maybe it won’t. It’s kind of niche, in retrospect.
But there you have it.
Leave a Reply
You must be logged in to post a comment.