Sorry! Internet Explorer is not supported on this site. Please view on Chrome, Firefox, or Edge.

Having fun at Zao is one of our values. We’ve put limited animated flourishes throughout our site to communicate our love of levity. We also recognize that onscreen movement is not fun or possible for everyone. We've turned off all our animations for you per your browser's request to limit motion. That said, we don't want you to miss out on the party.

Here's a funny joke to enjoy!

What do you get when you cross a dyslexic, an insomniac, and an agnostic?

Someone who lays awake at night wondering if there is a dog.

How to Save a Backslash (\) to CMB2 Meta Fields

Recently, we had a user request that their backslashes be preserved when saving their CMB2 fields. Typically, when a user wants non-standard sanitization, our canned response is to use the provided field parameter sanitization override, 'sanitization_cb'. If you’re not aware of this field parameter (and it’s cousin, 'escape_cb'), let me explain a bit.

By default, CMB2 does quite a bit of heavy-lifting for you when it comes to sanitizing your users’ input, as well as escaping that value for proper display. This is just one of the aspects of CMB2 that I appreciate; that I don’t have to “think” about the sanitization/escaping of my fields.

“It just works.”

Except, of course, when it doesn’t.

There is no way CMB2 can adapt to every scenario developers may use it for, and until AI has fully commandeered our society, I don’t foresee that happening. In the meantime, we built a way to handle those edge-case scenarios on your own.

Enter the humble 'sanitization_cb'.

Yep, that handy override has existed in CMB2 for over four (!) years, but it is a bit obscure, because, fortunately, you’ll almost never need it.

Back to the issue at hand. As I mentioned, this particular developer (that forum post is basically the TL;DR for this post) needed to allow users to add backslashes to their field. My first suggestion was to add this one-liner to their field config:

$cmb->add_field( array(
    'name' => '....',
    'id'   => '....',
    'type' => 'text',
    'sanitization_cb' => 'sanitize_text_field'
) );

This avoids CMB2’s default call to stripslashes_deep(), but still has the benefits of the sanitization.1

Unfortunately, as simple as it seemed, this was not the solution, as the backslashes were still being stripped from the content. So I started testing by doing some simple update_post_meta() calls, like:
update_post_meta( get_the_ID(), 'test_slashes', 'keep\my\slashes' );

Looking in the database, I found that the backslashes were still being removed. Huh.

Knowing that, I dove into the guts of update_metadata(), the update_post_meta() parent function. As you may have guessed, it turns out, WordPress itself removes the slashes, because it expects the data to be “slashed.” I’ll leave an explanation for why that is to someone else (read: I have no idea why, but probably has a good reason), but if you explicitly WANT the slashes, then you need to extra-slash it before it saves.

Armed with that knowledge, we can create a sanitization function that sanitizes and slashes:

 * Sanitizes a string from user input or from the database then add slashes to a string or array of strings.
 * This should be used when preparing data for core API that expects slashed data (like update_meta_data).
 * This should not be used to escape data going directly into an SQL query.
 * @see sanitize_text_field()
 * @see wp_slash()
 * @param  string $str String to sanitize/slash.
 * @return string Sanitized/slashed string.
function wp_slash_and_sanitize_text_field( $value ) {
    return wp_slash( sanitize_text_field( $value ) );

As you see, this is simply a mashup of the  sanitize_text_field() and wp_slash() functions, but it will serve us nicely for our sanitization_cb parameter:

$cmb->add_field( array(
    'name' => '....',
    'id'   => '....',
    'type' => 'text',
    'sanitization_cb' => 'wp_slash_and_sanitize_text_field'
) );

At this point, we’ve allowed this field to accept, save, and display the backslashes properly, and now you can too.

Thank you for following along. Like this parameter, there are many many useful, yet obscure, features in CMB2, and I hope to leverage future support requests and this space to add exposure for those features2.

  1. Keep in mind,  sanitize_text_field() works well for text fields, but different field-types will likely require a different sanitization method. 
  2. For instance, you should probably be know about the benefits to using the options_cb parameter. More to come… 

Leave a comment

Your email address will not be published.