Using Custom Sanitization Callbacks for Settings

Sometimes clients prefer to hide the “Read More/Continue” Reading link altogether. So, let’s give them the option to hide it and reveal it back if they want to.

Go ahead and put the following code at the end of the nd_dosth_customize_register action:

// Setting to Show/Hide Read More Link.
$wp_customize->add_setting( 'nd_dosth_show_readmore',
    array(
        'type'              => 'option',
        'default'           => true,
        'sanitize_callback' => 'nd_dosth_sanitize_checkbox',
        'transport'         => 'refresh',
    )
);

// Control to Show/Hide Read More Link.
$wp_customize->add_control( 'nd_dosth_readmore_text', 
    array(
        'type'        => 'checkbox',
        'section'     => 'nd_dosth_text_options',
        'label'       => 'Show Read More Link',
        'description' => 'Turn off this checkbox to hide Read More Link on Post archives',
    ) 
);

With the help of the above code, we are adding a “Show Read More Link” checkbox to the “Text Options” Section:

I have set the default value to “true” to make checkbox turned on by default. 

Although the checkbox control and the Setting are working just fine if you test it out, there is one problem.

We have provided a custom sanitization callback and we didn’t define it!

Yet! WordPress is failing silently by skipping sanitization altogether even if it can not find the function definition for the nd_dosth_sanitize_checkbox function. I just want to tell you this. 

Anyway, WordPress doesn’t ship with a callback function that sanitizes a checkbox and we definitely need to sanitize all our custom settings for security reasons and to avoid weird bugs.

So, we have to define our own sanitization callback and it’s not that difficult at all. 

In fact, we don’t have to break a sweat.

Ahmad Awais, one of the core developers of WordPress provided us with a neat collection of sanitization callbacks:

https://github.com/ahmadawais/WPCustomize/blob/master/customizer/customizer-sanitization.php

And for the purposes of this lesson, We just need the “checkbox” sanitization callback from the above collection.

So go ahead and paste the following code at the end of the nd_dosth_customize_register action:


/**
 * Checkbox sanitization callback example.
 *
 * Sanitization callback for 'checkbox' type controls. This callback sanitizes `$checked`
 * as a boolean value, either true or false.
 *
 * @param bool $checked Whether the checkbox is checked.
 * @return bool Whether the checkbox is checked.
 */
function nd_dosth_sanitize_checkbox( $checked ) {
    // Boolean check.
    return ( ( isset( $checked ) && true == $checked ) ? true : false );
}

The above sanitization callback just ensures that the checkbox value is either true or false and nothing else. That means, except for true or false, no other value will be stored in the database for this Setting. 

This is what sanitization is all about, right? No monkeying around with the data that gets stored in the database.

And the placement of this callback doesn’t really matter. You can put a sanitization callback inside functions.php or any other file that functions.php file includes. 

I placed it inside nd_dosth_customize_register action to keep everything that is related in one place. I usually move all the sanitization callbacks to another file and then include this file inside the nd_dosth_customize_register action. 

At the end of the day, it all boils down to your personal preferences.

Now, let’s go back to the blog-index.php template file and replace the following code:


<a class="read-more-link" href="<?php the_permalink(); ?>">
    <?php echo get_option( 'nd_dosth_readmore_text', __( 'Read More', 'nd_dosth' ) ); ?>
</a>

With:

<?php if( get_option('nd_dosth_show_readmore', true ) ): ?>
    <a class="read-more-link" href="<?php the_permalink(); ?>">
        <?php echo get_option( 'nd_dosth_readmore_text', __( 'Read More', 'nd_dosth' ) ); ?>
    </a>
<?php endif; ?>

We want to display the “Read More” link only if the “Show Read More Link” Setting is true, so we wrapped the “Read More” link inside an IF CONDITION which checks whether the “Show Read More Link” is true or false.

Our custom checkbox sanitization callback ensures that the get_option('nd_dosth_show_readmore', true ) will return false if the “Show Read More Link” checkbox is turned off. 

Pleasant, right?

Important Note: You can use a particular sanitization callback on any number of settings.

And that’s pretty much how to use our own sanitization callback and make our Customize Panel a better place.

Here is the updated blog-index.php template file:


<div class="blog-post">
    <?php if( is_front_page() || is_single() ): ?>
        <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
    <?php else: ?>
        <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
    <?php endif; ?>
    <?php if ( has_post_thumbnail() ) :
        $featured_image = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'dosth-blog-thumbnail' ); ?>
        <div class="blog-post-thumb">
            <a href="<?php the_permalink(); ?>"><img src="<?php echo $featured_image[0]; ?>" alt='' /></a>
        </div>
    <?php endif; ?>
    <?php the_excerpt(); ?>
    <?php if( get_option('nd_dosth_show_readmore', true ) ): ?>
        <a class="read-more-link" href="<?php the_permalink(); ?>">
            <?php echo get_option( 'nd_dosth_readmore_text', __( 'Read More', 'nd_dosth' ) ); ?>
        </a>
    <?php endif; ?>
    <?php $categories = get_the_category(); ?>
    <?php if ( ! empty( $categories ) ) : ?>
        <div class="posted-in">
            <span><?php _e( 'Posted In', 'nd_dosth' ); ?></span>
            <a href="<?php echo get_category_link( $categories[0]->term_id ); ?>"> 
                <?php echo $categories[0]->name; ?>
            </a>
        </div>
    <?php endif; ?>
</div>

In the next lesson, we will talk about Active Callbacks!