Title: Customizer APIs in 4.6 for Setting Validation and Notifications
Author: Weston Ruter
Published: July 5, 2016

---

 [  ](https://profiles.wordpress.org/westonruter/) [Weston Ruter](https://profiles.wordpress.org/westonruter/)
1:37 pm _on_ July 5, 2016     
Tags: [4.6 ( 140 )](https://make.wordpress.org/core/tag/4-6/),
[customize ( 67 )](https://make.wordpress.org/core/tag/customize/), [dev-notes ( 648 )](https://make.wordpress.org/core/tag/dev-notes/)

# Customizer APIs in 4.6 for Setting Validation and Notifications

As described in the [Improving Setting Validation in the Customizer](https://make.wordpress.org/core/2016/05/04/improving-setting-validation-in-the-customizer/)
proposal post and detailed in [#34893](https://core.trac.wordpress.org/ticket/34893)
and [#36944](https://core.trac.wordpress.org/ticket/36944), WordPress 4.6 includes
new APIs related to validation of CustomizerCustomizer Tool built into WordPress
core that hooks into most modern themes. You can use it to preview and modify many
of your site’s appearance settings. setting values. The Customizer has had sanitization
of setting values since it was introduced. Sanitization involves coercing a value
into something safe to persist to the database: common examples are converting a
value into an integer or stripping tags from some text input. As such, sanitization
is a _lossy_ operation.

But what happens in sanitization if a provided value is irrecoverable, beyond the
ability to sanitize? The Customizer did allow sanitizers to return `null` in such
cases which resulted in the value being skipped entirely from previewing and saving,
but there was **no feedback to the user that the value was skipped**. Additionally,
when multiple settings were modified but some were skipped due to returning `null`,
the result was that a save operation would only persist the non-skipped settings
to database: a user would unexpectedly find that only some of their settings were
applied, resulting in an **inconsistent saved state**. Save operations were not 
transactional/atomic.

These are the problems that the Customizer setting validation improvements in WordPress
4.6 are designed to address. With setting validation:

 1. All modified settings are validated up-front before any of them are saved.
 2. If any setting is invalidinvalid A resolution on the bug tracker (and generally
    common in software development, sometimes also _notabug_) that indicates the ticket
    is not a bug, is a support request, or is generally invalid., the Customizer save
    request is rejected: a save thus becomes _transactional_ with all the settings 
    left dirty to try saving again. (The Customizer [transactions proposal](https://make.wordpress.org/core/2015/01/26/customizer-transactions-proposal/)
    is closely related to setting validation here.)
 3. Validation error messages are displayed to the user, prompting them to fix their
    mistake and try again.

Sanitization and validation are also both part of the REST APIREST API The REST 
API is an acronym for the RESTful Application Program Interface (API) that uses 
HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application(
think “phone app” or “website”) can communicate with the data store (think “database”
or “file system”) [https://developer.wordpress.org/rest-api/](https://developer.wordpress.org/rest-api/)
infrastructure via `WP_REST_Request::sanitize_params()` and `WP_REST_Request::validate_params()`,
respectively. A setting’s value goes through validation before it goes through sanitization(
this is contrary to the [original proposal](https://make.wordpress.org/core/2016/05/04/improving-setting-validation-in-the-customizer/),
see [#36944](https://core.trac.wordpress.org/ticket/36944)).

## Validation Behavior

As noted above, if any setting is invalid, a Customizer save request is blocked.
When save request is rejected due to setting invalidity, the controls that have 
the invalid setting will get the error notifications added to them, and one of these
controls will be focused so that the user can correct the mistake. If there is an
control with an invalid setting in the current section expanded, then this is the
focus that will get the focus. Otherwise, the section containing an invalid control
will get expanded and the control then focused.

Validation of setting values on the server does not only occur when a save is attempted.
The setting values are validated and re-validated with each full refresh and selective
refresh, and the their validity states are returned from the server in the responses.
This means that setting validity will be reported in conjunction with updates to
the preview. This is important for a couple reasons:

 1. When a setting is invalid, the previewed value will render using the previously-
    saved value or the default setting value, so the notification provides an explanation
    for why their changes aren’t appearing in the preview.
 2. As soon as a value is corrected and the preview request finishes, the error notification
    will be removed from the control. This means the user doesn’t have to try to saving
    to see whether the value has been corrected or not.

This second point has a key implication for validating settings that are previewed
purely via JavaScriptJavaScript JavaScript or JS is an object-oriented computer 
programming language commonly used to create interactive effects within web browsers.
WordPress makes extensive use of JS for a better user experience. While PHP is executed
on the server, JS executes within a user’s browser. [https://www.javascript.com](https://www.javascript.com/)(
the `postMessage` transport _without_ selective refresh): you should perform the
validation logic for these using JavaScript as well. See [client-side validation](https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/?output_format=md#client-side-validation)
below.

## Adding Validation to a Setting

### Validate Callback

Just as you can supply a `sanitize_callback` when registering a setting, you can
also supply a `validate_callback` arg:

    ```notranslate
    $wp_customize->add_setting( 'established_year', array(
        'sanitize_callback' => 'absint',
        'validate_callback' => 'validate_established_year'
    ) );
    function validate_established_year( $validity, $value ) {
        $value = intval( $value );
        if ( empty( $value ) || ! is_numeric( $value ) ) {
            $validity->add( 'required', __( 'You must supply a valid year.' ) );
        } elseif ( $value < 1900 ) {
            $validity->add( 'year_too_small', __( 'Year is too old.' ) );
        } elseif ( $value > gmdate( 'Y' ) ) {
            $validity->add( 'year_too_big', __( 'Year is too new.' ) );
        }
        return $validity;
    }
    ```

Just as supplying a `sanitize_callback` arg adds a filterFilter Filters are one 
of the two types of Hooks [https://codex.wordpress.org/Plugin_API/Hooks](https://codex.wordpress.org/Plugin_API/Hooks).
They provide a way for functions to modify data of other functions. They are the
counterpart to Actions. Unlike Actions, filters are meant to work in an isolated
manner, and should never have side effects such as affecting global variables and
output. for `customize_sanitize_{$setting_id}`, so too supplying a `validate_callback`
arg will add a filter for `customize_validate_{$setting_id}`. Assuming that the `
WP_Customize_Setting` instances apply filters on these in their `validate` methods,
you can add this filter if you need to add validation for settings that have been
previously added.

The `validate_callback` and any `customize_validate_{$setting_id}` filter callbacks
take a `WP_Error` instance is its first argument (which initially is empty of any
errors added), followed by the `$value` being sanitized, and lastly the `WP_Customize_Setting`
instance that is being validated.

### Validate Method

A second way to add validation to a setting is by overriding the `validate` method
on a `WP_Customize_Setting` subclass. For example:

    ```notranslate
    class Established_Year_Setting extends WP_Customize_Setting {
        function validate( $value ) {
            if ( empty( $value ) || ! is_numeric( $value ) ) {
                return new WP_Error( 'required', __( 'You must supply a valid year.' ) );
            }
            if ( $value < 1900 ) {
                return new WP_Error( 'year_too_small', __( 'Year is too old.' ) ); 
            } 
            if ( $value > gmdate( 'Y' ) ) {
                return new WP_Error( 'year_too_big', __( 'Year is too new.' ) );
            }
            return true;
        }
    }
    ```

### Validating via Sanitization

The last way to add validation to a setting is to overload the sanitization routine
to include validation as well. Setting sanitization and setting validation are closely
related. Sanitization is for coercing/cleaning data. Validation is a pass/fail operation
and is key to prevent data from being accepted when it is “too far gone” to be recovered
from or when it is undesirable for the value to be silently and lossily cleaned.
As noted above, setting’s sanitization logic can continue to return `null` and this
will get interpreted as a setting’s value being invalid with a returned generic “
Invalid value” error. You may also return a `WP_Error` instance from a sanitization
routine which can be a handy way to consolidate the closely-related sanitization/
validation logic; if you do this, make sure that you opt to return `null` in WP≤
4.5, as otherwise this would result in a `WP_Error` instance being saved as a setting’s
value (!!):

    ```notranslate
    function sanitize_number( $value ) {
        $can_validate = method_exists( 'WP_Customize_Setting', 'validate' );
        if ( ! is_numeric( $value ) ) {
            return $can_validate ? new WP_Error( 'nan', __( 'Not a number' ) ) : null;
        }
        return intval( $value );
    }
    ```

Again, this useful if you want to consolidate the closely-related logic into a single
routine and also when to perform late validation after a value has been sanitized.

### Client-side Validation

As noted above, if you have a setting that is previewed purely via JavaScript (and
the `postMessage` transport _without_ selective refresh), you should also add client-
side validation as well. If you don’t then any validation errors will persist until
a refresh happens or a save is attempted. Client-side validation must not take the
place of server-side validation, since it would be trivial for a malicious user 
to bypass the client-side validation to save an invalid value if corresponding server-
side validation is not in place.

There is actually already a `validate` method available on the `wp.customize.Setting`
JSJS JavaScript, a web scripting language typically executed in the browser. Often
used for advanced user interfaces and behaviors. class (actually, the `wp.customize.
Value` base class). It was introduced with the inception of the Customizer in WP
3.4, although I believe it has been rarely utilized. The `validate` method’s name
is a bit misleading, as it actually behaves very similarly to the `WP_Customize_Setting::
sanitize()` PHPPHP The web scripting language in which WordPress is primarily architected.
WordPress requires PHP 7.4 or higher method. Nevertheless, the method can be used
to both sanitize and validate a value in JS. Note that this JS runs in the context
of the Customizer _pane_ not the preview, so any such JS should have `customize-
controls` as a dependency (not `customize-preview`) and enqueued during the `customize_controls_enqueue_scripts`
action. Some example JS validation:

    ```notranslate
    wp.customize( 'established_year', function ( setting ) {
    	setting.validate = function ( value ) {
    		var code, notification;
    		var year = parseInt( value, 10 );

    		code = 'required';
    		if ( isNaN( year ) ) {
    			notification = new wp.customize.Notification( code, {message: myPlugin.l10n.requiredYear} );
    			setting.notifications.add( code, notification );
    		} else {
    			setting.notifications.remove( code );
    		}

    		if ( isNaN( year ) ) {
    			return value;
    		}

    		code = 'year_too_small';
    		if ( year < 1900 ) {
    			notification = new wp.customize.Notification( code, {message: myPlugin.l10n.yearTooSmall} );
    			setting.notifications.add( code, notification );
    		} else {
    			setting.notifications.remove( code );
    		}

    		code = 'year_too_big';
    		if ( year > new Date().getFullYear() ) {
    			notification = new wp.customize.Notification( code, {message: myPlugin.l10n.yearTooBig} );
    			setting.notifications.add( code, notification );
    		} else {
    			setting.notifications.remove( code );
    		}

    		return value;
    	};
    } );
    ```

## Notifications APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.

An error notification is added to a setting’s `notifications` collection when a 
setting’s validation routine returns a `WP_Error` instance. Each error added to 
a PHP `WP_Error` instance is represented as a `wp.customize.Notification` in JavaScript:

 * A `WP_Error`‘s `code` is available as `notification.code` in JS.
 * A `WP_Error`‘s `message` is available as `notification.message` in JS. Note that
   if there are multiple messages added to a given error code in PHP they will be
   concatenated into a single message in JS.
 * A `WP_Error`‘s `data` is available as `notification.data` in JS. This is useful
   to pass additional error context from the server to the client.

Any time that a `WP_Error` is returned from a validation routine on the server it
will result in a `wp.customize.Notification` being created with a `type` property
of “error”.

While setting non-error notifications from PHP is not currently supported (see [#37281](https://core.trac.wordpress.org/ticket/37281)),
you can also add non-error notifications with JS as follows:

    ```notranslate
    wp.customize( 'blogname', function( setting ) {
        setting.bind( function( value ) {
            var code = 'long_title';
            if ( value.length > 20 ) {
                setting.notifications.add( code, new wp.customize.Notification(
                    code,
                    {
                        type: 'warning',
                        message: 'Theme prefers title with max 20 chars.'
                    }
                ) );
            } else {
                setting.notifications.remove( code );
            }
        } );
    } );
    ```

You can also supply “info” as a notification’s `type`. The default `type` is “error”.
Custom types may also be supplied, and the notifications can be styled with CSSCSS
Cascading Style Sheets. selector matching `notice.notice-foo` where “foo” is the
type supplied. A control may also override the default behavior for how notifications
are rendered by overriding the `wp.customize.Control#renderNotifications` method.

![Error notification](https://make.wordpress.org/core/files/2016/07/error-notification-
300x112.png)

![Warning notification](https://make.wordpress.org/core/files/2016/07/warning-notification-
300x110.png)

[⌊Info notification⌉⌊Info notification⌉[

![custom-notification](https://make.wordpress.org/core/files/2016/07/custom-notification-
300x113.png)

## More Examples

A couple plugins that make use of validation:

 * [Customize Validate Entitled Settings](https://gist.github.com/westonruter/1016332b18ee7946dec3):
   Demo that forces the site title, widgetWidget A WordPress Widget is a small block
   that performs a specific function. You can add these widgets in sidebars also
   known as widget-ready areas on your web page. WordPress widgets were originally
   created to provide a simple and easy-to-use way of giving design and structure
   control of the WordPress theme to the user. titles, and nav menu labels to be
   populated with title case and lacking exclamations and questions.
 * [Customize Posts](https://wordpress.org/plugins/customize-posts/): Validation
   errors added when posts would fail to save due to empty content, post locking,
   or save conflicts (with the specific conflicted fields being returned as `WP_Error``
   data`). This pluginPlugin A plugin is a piece of software containing a group 
   of functions that can be added to a WordPress website. They can extend functionality
   or add new features to your WordPress websites. WordPress plugins are written
   in the PHP programming language and integrate seamlessly with WordPress. These
   can be free in the WordPress.org Plugin Directory [https://wordpress.org/plugins/](https://wordpress.org/plugins/)
   or can be cost-based plugin from a third-party. also features syncing back the
   server-sanitized setting values to upon save, something which I think should 
   be in coreCore Core is the set of software required to run WordPress. The Core
   Development Team builds WordPress. at some point.
 * [Standalone Customizer Controls](https://github.com/xwp/standalone-customizer-controls):
   Demonstration of a controls used outside the Customizer with notifications added
   via JS based on HTML5 validity state.

## Summary of API Changes

PHP changes:

 * Introduces `WP_Customize_Setting::validate()`, `WP_Customize_Setting::$validate_callback`,
   and the `customize_validate_{$setting_id}` filter.
 * Introduces `WP_Customize_Manager::validate_setting_values()` to do validation(
   and sanitization) for the setting values supplied, returning a list of `WP_Error`
   instances for invalid settings.
 * Attempting to save settings that are invalid will result in the save being blocked
   entirely, with the errors being sent in the `customize_save_response`. Modifies`
   WP_Customize_Manager::save()` to check all settings for validity issues prior
   to calling their `save` methods.
 * Introduces `WP_Customize_Setting::json()` for parity with the other Customizer
   classes. This includes exporting of the `type`.
 * Modifies `WP_Customize_Manager::post_value()` to apply `validate` after `sanitize`,
   and if validation fails, to return the `$default`.
 * Introduces `customize_save_validation_before` action which fires right before
   the validation checks are made prior to saving.

JS changes:

 * Introduces `wp.customize.Notification` in JS which to represent `WP_Error` instances
   returned from the server when setting validation fails.
 * Introduces `wp.customize.Setting.prototype.notifications`.
 * Introduces `wp.customize.Control.prototype.notifications`, which are synced with
   a control’s settings’ notifications.
 * Introduces `wp.customize.Control.prototype.renderNotifications()` to re-render
   a control’s notifications in its notification area. This is called automatically
   when the notifications collection changes.
 * Introduces `wp.customize.settingConstructor`, allowing custom setting types to
   be used in the same way that custom controls, panels, and sections can be made.
 * Injects a notification area into existing controls which is populated in response
   to the control’s `notifications` collection changing. A custom control can customize
   the placement of the notification area by overriding the new `getNotificationsContainerElement`
   method.
 * When a save fails due to setting invalidity, the invalidity errors will be added
   to the settings to then populate in the controls’ notification areas, and the
   first such invalid control will be focused.

[#4-6](https://make.wordpress.org/core/tag/4-6/), [#customize](https://make.wordpress.org/core/tag/customize/),
[#dev-notes](https://make.wordpress.org/core/tag/dev-notes/)

### Share this:

 * [  Threads ](https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/?share=threads)
 * [  Mastodon ](https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/?share=mastodon)
 * [  Bluesky ](https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/?share=bluesky)
 * [  X ](https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/?share=x)
 * [  Facebook ](https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/?share=facebook)
 * [  LinkedIn ](https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/?share=linkedin)

 1.  ![](https://secure.gravatar.com/avatar/19347ef87f4fd5978b2184e7f05af5c780485f69dbfdefccfe3521c732a87f06?
     s=32&d=mm&r=g)
 2.   [Drew Jaynes](https://profiles.wordpress.org/drewapicture/)  5:28 pm _on_ July
     5, 2016
 3.  Neat-o. Thanks for the great write-up [@westonruter](https://profiles.wordpress.org/westonruter/)!
 4.  ![](https://secure.gravatar.com/avatar/ecdd0d5d058234d40e10c4a1440540f3402ed4e325c136d88aa4ef4eed3874a9?
     s=32&d=mm&r=g)
 5.   [Rohit Tripathi](https://profiles.wordpress.org/rohitink/)  4:00 am _on_ July
     6, 2016
 6.  Looking forward to using the Notifications APIAPI An API or Application Programming
     Interface is a software intermediary that allows programs to interact with each
     other and share data in limited, clearly defined ways.. Great Feature. 😊
 7.  ![](https://secure.gravatar.com/avatar/0608b540c7da83b396fd9a453ad1ac0298152522bc3a06888d41649e4024a089?
     s=32&d=mm&r=g)
 8.   [Ahmad Awais](https://profiles.wordpress.org/mrahmadawais/)  4:26 am _on_ July
     6, 2016
 9.  Awesome sauce 🙂
 10. ![](https://secure.gravatar.com/avatar/7b4c8e2413c3cf4768d958fa7257e7f2585760d399a686b0c2e86415b8c796b4?
     s=32&d=mm&r=g)
 11.  [nikeo](https://profiles.wordpress.org/nikeo/)  5:57 am _on_ July 6, 2016
 12. Really useful improvements as usual, and clear explanations. Thanks guys
 13. ![](https://secure.gravatar.com/avatar/a2bc635dbb769b261b9362fdd1dadb0ef44eff7708a9459d4364de89b7452ee4?
     s=32&d=mm&r=g)
 14.  [Puneet Sahalot](https://profiles.wordpress.org/puneetsahalot/)  8:24 pm _on_
     July 26, 2016
 15. Simply perfect!
 16. ![](https://secure.gravatar.com/avatar/64b51769e7b80312023eb6c3f766cb512cf79adf7265812b15442f9573a9a056?
     s=32&d=mm&r=g)
 17.  [Tran Ngoc Tuan Anh](https://profiles.wordpress.org/rilwis/)  1:45 am _on_ August
     17, 2016
 18. This is an awesome feature!
 19. ![](https://secure.gravatar.com/avatar/584d016d15d686b4d01bf708178993cb74ef8f7fd683c6d1e5d5d7483976dd24?
     s=32&d=mm&r=g)
 20.  [banarsiamin](https://profiles.wordpress.org/banarsiamin/)  6:16 am _on_ August
     19, 2016
 21. Looking forward to using the Notifications APIAPI An API or Application Programming
     Interface is a software intermediary that allows programs to interact with each
     other and share data in limited, clearly defined ways.. Great Feature. 😊

Comments are closed.

# Post navigation

[← This Week in 4.6: July 4 – 10](https://make.wordpress.org/core/2016/07/04/this-week-in-4-6-july-4-10/)

[Customize API Changes in 4.6 →](https://make.wordpress.org/core/2016/07/06/customize-api-changes-in-4-6/)