When working with the Settings API (or any other API that handles options, serialization, validation, and page redirections), dealing with custom messages in WordPress isn’t something that we typically have to worry about it.
The API takes care of all of that for us, and if we need to use other pieces of information, like the query string, we’re able to take advantage of API functions like
get_query_var to check for the presence of a given value without much thought for how it was added in the first place.
But what about when you’re working on your administration page, and you need to display custom messages in WordPress after a redirect?
Custom Messages in WordPress
Specifically, let’s state the problem like this:
What if you need to display custom messages in WordPress after performing a safe redirect and don’t have access to the information by traditional means?
The challenge is that using a custom implementation of an administration page – which is okay depending on the project – often requires a safe redirect.
And this can trash different things (like query string variables), so we’re left having to come up with a way to display custom messages.
Looking at a Safe Redirect
For this example, let’s assume that the project in question has all of the necessary things in place to make sure data is saving securely.
- A WordPress nonce,
- The presence of the
_wp_http_referervariable in the
- And proper sanitization.
Next, let’s also assume that the redirect is being performed by the
wp_safe_redirect function versus another given PHP function or another type of magic to get the user to the desired page.
This function does the following:
Checks whether the $location is using an allowed host, if it has an absolute path. A plugin can therefore set or remove allowed host(s) to or from the list.
If the host is not allowed, then the redirect is to wp-admin on the siteurl instead. This prevents malicious redirects which redirect to another host, but only used in a few places.
With that, the initial version of the function might look something like this:
It’s straightforward enough and should be clear as to what it’s doing (especially given the code comments). In short, we want to redirect back to the URL that ultimately results in hitting this function in the first place.
In the context of an administration page, this is typically the page from which the user came. And once there, it’s time to display custom messages. Perhaps these messages are error messages, notices, success messages, whatever.
So what now?
Saving Custom Messages
There are likely different ways to do this, but the one I’ve found to be the most maintainable and easiest to follow uses the following:
- Create a class or an area in your code where you’re going to maintain the errors,
- Create a function responsible for saving the errors to the database,
- Create a function responsible for retrieving the errors,
- Delete the errors once you’ve retrieved them,
- Render them on the front-end.
Depending on how you structure your work you may not need a class, and you may already have functions available that can do some of this. To that end, I won’t bother walking through an entire example for how this can be achieved with a set of classes and what not.
Instead, I’ll focus on the core points that are [hopefully] applicable to projects of various architectures.
With that said, I know it reads like it’s a lot to do. Depending on how you’re used to working with administration pages, it might seem different but it’s not really that much extra work and you have more control over how the errors are managed in the context of your project.
For the remainder of this post, I’ll walk through how get the information into the database and then, in the next post, I’ll walk through how to retrieve the information and make sure that it renders correctly each time on the administration page.
First, I’m assuming that you have some place in your code where you’re saving your options, your settings, or other information that you’re going to need throughout your project.
Since you’re working with a custom administration page, then you’re going to need a way to do this. So, in this example, I’m going to assume that function is a good place to store all of your error messages, success messages, query string variables, and so on.
In my code, I have a simple
save function that does the following:
- Initializes a class responsible for maintaining a collection of messages (I call it a
Settings_Messengerand I refer to it, in code, via
- Next, the cakes sure the user has permission to save. If not, an error message will be added to the collection.
- Saves the settings.
- Redirects back to the page.
Given all of the above, the function looks like this:
Here’s the thing: When working with certain APIs, we’re used to WordPress taking care of displaying any error messages for us. But if we’re going with this approach, we need to take care of this in our own way.
Notice in the code above, I’m making a call to
add_error_message. This makes a call into my
Settings_Messenger which maintains an array used to store these messages.
When the time comes, the incoming message will be sanitized and then serialized:
The serialization function is simple, too: All it does is take the collection messages and saves them to an option in the database:
update_option so that it will update whatever errors were there before because, if this is structured properly, the array will not change until the object is re-instantiated (which will happen when the page is refreshed after a redirect).
Why Bother with Custom Messages?
The reason that I’m spending time walking through this is because there are times in certain projects where you may want to display more rich information about what’s being saved to the database.
In that case, you’re going to need to take advantage of displaying custom messages in WordPress. Case in point: It’s not enough to save that there was a problem saving the information. Instead, why not provide a list of what failed to save?
Sometimes, giving this much information away is an issue of security. But in this series of posts, I’m not talking about giving away whether or not someone’s password failed. Instead, this is about information the user if they’ve provided something like a malformed email address or they didn’t provide a file path in the correct format.
In the next post, I’ll show how to follow-up with the strategy above to render the information on the front-end.