Customize API Changes in 4.6

This post contains a summary of the developer-oriented changes and additions to the customize 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. in WordPress 4.6. View all 4.6 customize tickets here. The biggest new customize developer feature in 4.6 is setting validation, which has a dedicated post with details:

https://make.wordpress.org/core/2016/07/05/customizer-apis-in-4-6-for-setting-validation-and-notifications/

Clean up 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. Media Control CSSCSS Cascading Style Sheets. (#30618)

When the customizer media controls were modernized in WordPress 4.1, timeline considerations required the improvements to ship with a confusing and untenable markup structure and the resulting requirement to use separate CSS selectors for each sub-control of WP_Customize_Media_Control.

In 4.6, the markup of the coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. media controls has been simplified and the CSS completely refactored to allow media controls to share common CSS selectors. As a result, custom controls that use part of the core UIUI User interface and subclass WP_Customize_Media_Control no longer need to create their own CSS styles that duplicate core rules. Because the markup and styling has changed significantly, please test any custom controls, CSS, or 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/. that is related to media controls in the customizer.

Customize Value Hook Receives Context (#36452)

The customize_value_{$id_base} filterFilter Filters are one of the two types of 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. now passes $this (the WP_Customize_Setting instance) as a second parameter, after the setting value. This provides access to all of the methods and parameters of the specific setting whose value is being filtered and brings this hook inline with the other hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. in WP_Customize_Setting.

Allow the Nav Menu Item Type Label (among other things) to be filtered (#35203)

The wp_setup_nav_menu_item filter is now applied consistently to all customizer settings representing nav menu items. The filter was previously used in WP_Customize_Nav_Menu_Item_Setting::value() but not in WP_Customize_Nav_Menu_Item_Setting::value_as_wp_post_nav_menu_item(), and is the same filter that’s used for the Menus screen in wp-adminadmin (and super admin).

Other Improvements

  • You can now use the Esc key to close the currently expanded section or panel (or 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./nav menu item control). See #22237.
  • The Custom Menu widget now includes a shortcut to edit a selected menu in the customizer. Navigating out of the nav menu section returns focus back to the Custom Menu widget where the shortcut button was clicked. See #32683.
  • When previewing a new theme in the customizer, clicking Activate will no longer result in being navigated out of the customizer and onto the frontend. See #35320.
  • The get_custom_logo filter now includes a blogblog (versus network, site) parameter. See #36639.
  • The menu locations section in the customizer now includes buttons to edit each selected menu. See #36795.
  • There is now a link to the widgets panel in the menu locations section description. See #36796.

#4-6, #customize, #dev-notes

Customizer APIs in 4.6 for Setting Validation and Notifications

As described in the Improving Setting Validation in the Customizer proposal post and detailed in #34893 and #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 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/. 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, see #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/. (the postMessage transport without selective refresh): you should perform the validation logic for these using JavaScript as well. See 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:

$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. 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:

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 (!!):

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:

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), you can also add non-error notifications with JS as follows:

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

Warning notification

Info notification

custom-notification

More Examples

A couple plugins that make use of validation:

  • Customize Validate Entitled Settings: 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: 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/ 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: 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, #customize, #dev-notes

Categories and Tags screens changes in 4.6

In WordPress 4.6 the Categories and Tags screens (and all the custom terms screens that use the same edit-tags.php page) will change in order to make the visual order of the main elements match the tab order. This change is focused on helping people who use the keyboard to navigate the content or use assistive technologies such as screen readers.

If you’re a 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/ or can be cost-based plugin from a third-party or theme author and you’re providing custom functionalities in these screens, there are a few things you should check.

Why it matters

For accessibilityAccessibility Accessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility), the visual order should always match the tab order. The main functionality in a page should just be the first thing in the source markup and other parts of the user interface should never be “skipped”.

The screenshot below illustrates the current Tags screen. The main content is split in two columns. The first element in the source is the right column with the table to list the terms followed by the tagtag A directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.) cloud for the popular tags and the form to add new tags.

Tags screen visual order and tab order

The current order of the main content elements in the Tags screen.

On page load, the initial focus is set on the first focusable field in the form which is the third and last blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. of content in the page.

When using the keyboard or a screen reader, content navigation is a linearised process. Starting from the form to add new terms makes sense since this is the main task on these screens. But then users will move forward and they will find just the footer of the page. When relevant parts of content are skipped, it’s more likely for screen reader users to be confused or experience difficulty navigating pages. They just don’t have a clue there is something “before” their navigation starting point. Keyboard users will have to tab backwards to get to the previous content.

What is going to change

The two columns in these screens will be swapped. The first one in the source will be the left column, followed by the right column. Also, in the Tags screen, the tag cloud will be moved after the form. Visually, this change will make these two screens more consistent. From an accessibility point of view, the content structure and organization will be easier to understand and navigate.

The new categories screen

The new Categories screen.

The new tag screen

The new tag screen.

Things you should check

  • if you’re using CSSCSS Cascading Style Sheets. or jQuery selectors for your added functionalities, you should consider the order of the elements in the markup has changed
  • there are a number of action hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. and filters in these screens but basically just one will have a different order, see the related ticketticket Created for both bug reports and feature development on the bug tracker. for more details

For more in-depth information see the related TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.Trac An open sourceOpen Source Open Source denotes software for which the original source code is made freely available and may be redistributed and modified. Open Source **must be** delivered via a licensing model, see GPL. project by Edgewall Software that serves as a bugbug A bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker.: Edit term screens: tab order should match visual order.

Get ahead of 4.6 and update now!

If you’re a theme or plugin developer: now is a great time to check your code! Help us to make the Web a place designed to work for all people. Any feedback and thoughts are more than welcome, please let us know in the comments below.

#4-6, #accessibility, #dev-notes