New esc_xml() function in WordPress 5.5

As part of the development for the new XML Sitemaps feature in WordPress 5.5, a new esc_xml() function has been added to coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. that filters a string cleaned and escaped for output in XML. This joins the existing set of functions like esc_html() and esc_js().

While all contents in XML sitemaps are already escaped using this new function, existing code in WordPress core can be updated to leverage it in future releases.

wp_kses_normalize_entities() has been updated accordingly to support this, and now can distinguish between HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. and XML context.

Note: l10nL10n Localization, or the act of translating code into one's own language. Also see internationalization. Often written with an uppercase L so it is not confused with the capital letter i or the numeral 1. WordPress has a capable and dynamic group of polyglots who take WordPress to more than 70 different locales. helpers like esc_xml__() and esc_xml_e() are being proposed separately in #50551, and are not part of this release.

#5-5, #dev-notes, #sitemaps, #xml-sitemaps

Editing Images in the Block Editor

As most people that follow coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. development already know, a new feature in WordPress 5.5 is editing of images right in the block editor.

The new image editor looks a lot better and is much easier to use. It comes with several presets allowing the users to quickly adjust the aspect ratio, zoom level, and position.

Editing an image in the image block, aspect ration drop-down open.

There are two notable changes:

  • Image editing is done through 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/.. The new functionality is in WP_REST_Attachments_Controller and introduces wp_edited_image_metadata 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.. Of course all other actions and filters triggered when image sub-sizes are created and saved still work.
  • After editing, the image is saved separately as a new attachment. This lets the users have full control: see the edited image in the Media Library, edit either the original or the edited image again, or delete any of them if not used. (In the old image editor the edited images are saved in the image metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. reusing the same attachment, and the users cannot access the original “parent” image).

When creating new attachments for edited images the post_title, post_content (image description), post_excerpt (caption stored in the database), and the alt text (stored in post meta in the database) are copied (if present) from the parent image to the edited image. Also the EXIF data stored in image meta is merged.

For plugins, the new wp_edited_image_metadata filter can also be used to migrate any other meta data 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 may be adding to image attachments, or to save new data.

#5-5, #dev-notes

Introducing createInterpolateElement

With the release of WordPress 5.5 there will be a new function available on the wp.element package, createInterpolateElement.

This function creates an interpolated element from a passed in string with specific tags matching how the string should be converted to an element or ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. node given a conversion map value.

This function offers the ability to handle a couple use-cases:

  • When you have a template string with placeholders for where you inject known htmlHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. elements or React components.
  • When you have a translationtranslation The process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. string where you want to communicate placeholders for html elements to those translating the string.

One problem with the above use-cases in the past has been preserving the security of html string rendering within react without using RawHTML or dangerouslySetInnerHTML.

Of course the second use-case above is the primary one for which this function was created. As an example, for the given string:

"This is a <span class="special-text">string</span> with a <a href="https://make.wordpress.org">link</a> and a self-closing <CustomComponent />."

You could make the above translatable via doing something like this:

import { __ } from '@wordpress/i18n';
import { createInterpolateElement } from '@wordpress/element';
import { CustomComponent } from '../custom-component.js';

const translatedString = createInterpolateElement(
  __( 'This is a <span>string</span> with a <a>link</a> and a self-closing <custom_component/>.' ),
  {
    span: <span className="special-text" />,
    a: <a href="https://make.wordpress.org"/>,
    custom_component: <CustomComponent />,
  }
);

#5-5, #core-js, #dev-notes

Passing arguments to template files in WordPress 5.5

For years, theme developers wishing to pass data to template files have had to use less than ideal workarounds. This included the use of global variables, set_query_var(), the include( locate_template() ) pattern, or own version of get_template_part(), and so on.

Starting in WordPress 5.5, the template loading functions will now allow additional arguments to be passed through to the matched template file using a new $args parameter.

Affected functions

  1. get_header()
  2. get_footer()
  3. get_sidebar()
  4. get_template_part()
  5. locate_template()
  6. load_template()

To provide proper context, the related 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. have also been updated to pass this new $args parameter.

  • get_header
  • get_footer
  • get_sidebar
  • get_template_part_{$slug}
  • get_template_part

Note: get_search_form() already accepts and passes additional arguments to search form templates as of [44956]. However, the $args parameter was added to the related hooks at the same time as the ones above. These are:

  • pre_get_search_form (action)
  • search_form_format (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.)
  • get_search_form (filter)

Example

<?php
get_template_part( 
    'foo', 
    null, 
    array( 
        'class'          => 'user',
        'arbitrary_data' => array(
            'foo' => 'baz',
            'bar' => true,
        ),
        ...
    )
);

In the above example, the additional data passed to get_template_part() through the $args variable can be accessed within the foo.php template through the locally scoped $args variable.

<?php
// Example foo.php template.

// Set defaults.
$args = wp_parse_args(
    $args,
    array(
        'class'          => '',
        'arbitrary_data' => array(
            'foo' => 'fooval',
            'bar' => false,
        ),
        ...
    )
);
?>

<div class="widget <?php echo esc_html_class( $args['class'] ); ?>">
    <?php echo esc_html( $args['arbitrary_data']['foo'] ); ?>
</div>

Note: Any template file that currently contains an $args variable should take care when utilizing this new feature. Any modifications to $args in the loaded template files will override any values passed through using the above functions.

This enhancementenhancement Enhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. ticketticket Created for both bug reports and feature development on the bug tracker. was created 8 years ago, and is a long awaited addition. Thank you to all that helped discuss and refine this change.

For reference, see the related TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticket: #21676.

Props @audrasjb and @desrosj for technical review and proofreading.

#5-5, #dev-notes

New and modified REST API endpoints in WordPress 5.5

In WordPress 5.5, a handful of entirely new 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/. endpoints have been introduced and several others will see new features or enhancements. Let’s look at a breakdown of these changes.

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. Types

In [48173] REST API endpoints were introduced to return all of the block types registered on the server.

  • GET /wp/v2/block-types will return all registered block types.
  • GET /wp/v2/block-types/core will return all blocks within the core namespace.
  • GET /wp/v2/block-types/core/quote will return the definition specifically for the coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. quote block.

This endpoint is accessible to users that have edit permission for any post type that is included in the REST API. In other words, if the user can edit posts in the Block Editor, they can access the block types endpoint.

Response Format

The response format for this endpoint closely follows the Block Type Registration RFC. The JSON Schema documents the full response type. The following is an example of that in practice for the core/quote block.

{
  "attributes": {
    "value": {
      "type": "string",
      "source": "html",
      "selector": "blockquote",
      "multiline": "p",
      "default": ""
    },
    "citation": {
      "type": "string",
      "source": "html",
      "selector": "cite",
      "default": ""
    },
    "align": {
      "type": "string"
    }
  },
  "is_dynamic": false,
  "name": "core/quote",
  "title": "",
  "description": "",
  "icon": null,
  "category": "text",
  "keywords": [],
  "parent": null,
  "provides_context": [],
  "uses_context": [],
  "supports": {
    "anchor": true
  },
  "styles": [],
  "textdomain": null,
  "example": null,
  "editor_script": null,
  "script": null,
  "editor_style": null,
  "style": null
}

For more information, refer to the relevant ticketticket Created for both bug reports and feature development on the bug tracker. on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. (#48173).

Plugins

In [48242] REST API endpoints were introduced for managing plugins. These endpoints facilitate the Block Directory Inserter feature in the block editor.

  • GET /wp/v2/plugins will return a list of all plugins installed on a site.
  • GET /wp/v2/plugins/akismet/akismet will return information about the installed Akismet 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. The first akismet refers to the plugin’s folder, the second akismet is the main plugin file without the .php file extension.
  • POST /wp/v2/plugins { slug: "akismet" } installs the plugin with the slug aksimet from the WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ plugin directory. The endpoint does not support uploading a plugin zip.
  • PUT /wp/v2/plugins/akismet/akismet { status: "active" } activates the selected plugin. The status can be set to network-active to networknetwork (versus site, blog) activate the plugin on Multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site. To deactivate the plugin set the status to inactive. There is not a separate network-inactive status, inactive will perform a network deactivation if the plugin was network activated.
  • DELETE /wp/v2/plugins/akismet/akismet uninstalls the selected plugin. The plugin must be inactive before deleting it.

The endpoint is accessible to authenticated users with the activate_plugins capability. Specific actions have their own additional permission checks. For instance, the install_plugins capability is required to install new plugins.

Response Format

The JSON Schema for the endpoint documents the full response type. The following is an example for the Akismet plugin.

{
  "plugin": "akismet/akismet",
  "status": "inactive",
  "name": "Akismet Anti-Spam",
  "plugin_uri": "https://akismet.com/",
  "author": "Automattic",
  "author_uri": "https://automattic.com/wordpress-plugins/",
  "description": {
    "raw": "Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from spam</strong>. It keeps your site protected even while you sleep. To get started: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key.",
    "rendered": "Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from spam</strong>. It keeps your site protected even while you sleep. To get started: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key. <cite>By <a href=\"https://automattic.com/wordpress-plugins/\">Automattic</a>.</cite>"
  },
  "version": "4.1.6",
  "network_only": false,
  "requires_wp": "",
  "requires_php": "",
  "text_domain": "akismet"
}

For more information, refer to the relevant ticket on Trac (#50321).

Block Directory

The [48242] changeset also introduced an endpoint for searching the WordPress.org block directory.

GET /wp/v2/block-directory/search?term=starscape searches for blocks that match the term starscape.

This endpoint requires both the activate_plugins and install_plugins capabilities.

Response Format

The JSON Schema for the endpoint documents the full response type. The following is an example for the Starscape block.

{
  "name": "a8c/starscape",
  "title": "Starscape Block",
  "description": "Everything was made of collapsing stars, we are all made of star stuff. Now we also can create content in WordPress with stars in motion. Requirements As this is part...",
  "id": "starscape",
  "rating": 0,
  "rating_count": 0,
  "active_installs": 10,
  "author_block_rating": 0,
  "author_block_count": 1,
  "author": "Automattic",
  "icon": "https://ps.w.org/starscape/assets/icon.svg?rev=2232475",
  "assets": [
    "https://ps.w.org/starscape/tags/1.0.2/index.js?v=1591313160",
    "https://ps.w.org/starscape/tags/1.0.2/editor.css?v=1591313160",
    "https://ps.w.org/starscape/tags/1.0.2/style.css?v=1591313160"
  ],
  "last_updated": "2020-06-04T23:26:00",
  "humanized_updated": "1 month ago",
  "_links": {
    "wp:install-plugin": [
      {
        "href": "http://trunk.test/wp-json/wp/v2/plugins?slug=starscape"
      }
    ]
  }
}

For more information, refer to the relevant ticket on Trac (#50321).

Image Editing

In [48291] an endpoint was introduced for editing image attachments in the media library. This facilitates the inline image editing feature in the block editor.

POST /wp/v2/media/5/edit edits the image with id 5. This rotates the image 90 degrees, and then zooms the image to 80% of its original height and width into the top-left corner.

{
  "x": 0,
  "y": 0,
  "width": 80,
  "height": 80,
  "rotate": 90
}

Notes: width and height only supports percentage values. x & y specify the crop starting point.

This endpoint requires permission to edit the original attachment as well as the upload_files capability. The endpoint returns the newly created attachment.

For more information, refer to the relevant ticket on Trac (#44405).

Block Renderer

Every block has a different set of attributes. These attributes are specified as a JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. Schema object. Previously, every block registered its own block renderer route using its attributes for the schema. This allowed for the attributes to be validated using the built in endpoint validation rules.

However, this approach had the unfortunate side effect of creating a large number of nearly identical REST API routes (one for each dynamic block). Each registered route has a performance impact. As the number of server side blocks goes up, this becomes more and more of an issue.

In [48069], the block renderer route was changed to register a single block renderer route and dynamically validate the attributes based on the selected block. This is an internal only change, consumers of the block renderer endpoint shouldn’t notice any changes. The same request format continues to work.

However, this means the attributes schema for a block can no longer be fetched by making an OPTIONS request to the block renderer endpoint. The new block types endpoint should be used instead.

In [47756] support for the POST request method was added to the block renderer. This allows a block to be rendered that has attributes larger than would be allowed in the URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org.

For more information, refer to the tickets on Trac (#49680 and #48079).

Themes

In [47921], support for returning the majority of a theme’s headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. information from its public style.css file was added to the /wp/v2/themes endpoint. Previously, only the theme’s supported features were returned.

For example, Twenty Twenty now produces the following response:

{
  "stylesheet": "twentytwenty",
  "template": "twentytwenty",
  "requires_php": "5.2.4",
  "requires_wp": "4.7",
  "textdomain": "twentytwenty",
  "version": "1.4",
  "screenshot": "http://trunk.test/wp-content/themes/twentytwenty/screenshot.png",
  "author": {
    "raw": "the WordPress team",
    "rendered": "<a href=\"https://wordpress.org/\">the WordPress team</a>"
  },
  "author_uri": {
    "raw": "https://wordpress.org/",
    "rendered": "https://wordpress.org/"
  },
  "description": {
    "raw": "Our default theme for 2020 is designed to take full advantage of the flexibility of the block editor. ",
    "rendered": "Our default theme for 2020 is designed to take full advantage of the flexibility of the block editor."
  },
  "name": {
    "raw": "Twenty Twenty",
    "rendered": "Twenty Twenty"
  },
  "tags": {
    "raw": [
      "blog",
      "one-column",
      "custom-background",
      "custom-colors",
      "custom-logo",
      "custom-menu"
    ],
    "rendered": "blog, one-column, custom-background, custom-colors, custom-logo, custom-menu"
  },
  "theme_uri": {
    "raw": "https://wordpress.org/themes/twentytwenty/",
    "rendered": "https://wordpress.org/themes/twentytwenty/"
  },
  "theme_supports": {}
}

Currently, themes can declare support for a given feature by using add_theme_support(). In [48171], the register_theme_feature 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. was introduced that allows WordPress Core and plugins to declare a list of available features that themes can support.

The REST API uses this to expose a theme’s supported features if the feature has been registered with show_in_rest set to true.

As a reminder, the themes endpoint is available to any users who can edit a post type that is visible in the REST API. In other words, if a user can use the Block Editor, they can access this information.

For more information, refer to the relevant tickets on Trac (#49906 and #49406).

Props @desrosj and @justinahinon for reviewing.

#5-5, #dev-notes, #rest-api

REST API Parameter & JSON Schema changes in WordPress 5.5

WordPress 5.5 introduces a number of new features and changes to how request and response parameters are handled, particularly around JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. Schema features.

General

Support more JSON Schemas when filtering a response by context

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/. uses context to remove fields from a response if the user does not have adequate permissions or for performance reasons. For example, in the following schema, if the user requested the resource with context=view, only the name properties would be returned.

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "context": [ "view", "edit" ]
    },
    "role": {
      "type": "string",
      "context": [ "edit" ]
    }
  }
}

In [47758], support was added for removing more properties from a response if additional features were in use. The array type, multi-types, and the additionalProperties keyword are now supported. Additionally, the 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. recurses to an infinite depth.

So for the following schema, if the resource was requested with context=view the following fields would be returned.

{
  "type": "object",
  "properties": {
    "notes": {
      "context": [ "view", "edit" ],
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "note": {
            "context": [ "view", "edit" ],
            "type": "string"
          },
          "ip": {
            "context": [ "edit" ],
            "type": "string"
          }
        }
      }
    }
  }
}

Note that the ip field has been omitted.

{
  "notes": [
    {
      "note": "My Note"
    }
  ]
}

For more information, see #48819 on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress..

Inconsistent parameter type handling in WP_REST_Request::set_param()

Previously, when parameters were manually added to a WP_REST_Request object using set_param(), the parameter was added into the first available parameter slot. This could be unexpected if a parameter was already in another parameter slot and you were trying to overwrite the value.

In [47559], this changed to first look for an existing parameter, and then falls back to the first parameter in the order if none was found.

For more information, refer to the relevant Trac ticketticket Created for both bug reports and feature development on the bug tracker. (#40838).

WP_REST_Controller::get_endpoint_args_for_item_schema drops some keywords

The primary mechanism for developers to declare the parameters an endpoint accepts is by writing a JSON Schema in WP_REST_Controller::get_item_schema(). The schema is then transformed into the args format by using WP_REST_Controller::get_endpoint_args_for_item_schema() during route registration. This transformation process dropped the minimum, maximum, exclusiveMinimum, and exclusiveMaximum JSON Schema keywords. This list of allowed keywords was updated in [47911] to ensure this doesn’t happen.

For more information, check out #50301 on Trac.

Check required properties are provided when validating an object

Previously, the REST API would validate that all parameters with the required attribute were provided in WP_REST_Request::has_valid_params. This meant that if an object was defined with its own set of required parameters, it was not checked by the default parameter validator.

So, for instance, given the following schema, the request would be accepted despite the missing version field.

{
  "type": "object",
  "properties": {
    "fixed_in": {
      "required": true,
      "type": "object",
      "properties": {
        "revision": {
          "required": true,
          "type": "integer"
        },
        "version": {
          "required": true,
          "type": "string"
        }
      }
    }
  }
}
{
  "fixed_in": {
    "revision": 47809
  }
}

In [47809] this was fixed to now generate a rest_property_required error.

Version 4 syntax

This change also adds support for JSON Schema Version 4 required-property syntax where the list of required properties for an object is defined as an array of property names. This can be particularly helpful when specifying that a metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. value has a list of required properties.

Given the following meta field.

register_post_meta( 'post', 'fixed_in', array(
	'type'         => 'object',
	'show_in_rest' => array(
		'single' => true,
		'schema' => array(
			'required'   => array( 'revision', 'version' ),
			'type'       => 'object',
			'properties' => array(
				'revision' => array(
					'type' => 'integer',
				),
				'version'  => array(
					'type' => 'string',
				),
			),
		),
	),
) );

And the following request object.

{
	"title": "Check required properties",
	"content": "We should check that required properties are provided",
	"meta": {
		"fixed_in": {
			"revision": 47089
		}
	}
}

The following error will be returned.

{
  "code": "rest_property_required",
  "message": "version is a required property of meta.fixed_in.",
  "data": {
    "status": 400
  }
}

If the fixed_in meta field was omitted entirely, no error would be generated. An object that defines a list of required properties does not indicate that the object itself is required to be submitted. Just that if the object is included, that the listed properties must also be included as well.

Specifying the required properties in the top-level schema for an endpoint using a required array is not supported. Given the following schema, a user could successfully submit a request without the title or content properties. This is because, as discussed earlier, the schema document is not itself used for validation, but instead transformed to a list of parameter definitions.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "my-endpoint",
  "type": "object",
  "required": [ "title", "content" ],
  "properties": {
    "title": {
      "type": "string"
    },
    "content": {
      "type": "string"
    }
  }
}

For more information, refer to #48818 on Trac.

Make multi-typed schemas more robust

A multi-type schema is a schema where the type keyword is an array of possible types instead of a single type. For instance, [ 'object', 'string' ] would allow objects or string values.

In [46249] basic support for these schemas was introduced. The validator would loopLoop The Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. over each schema type trying to find a version that matched. This worked for valid values, but for 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. values it provided unhelpful error messages. The sanitizer also had its utility restricted.

In [48306], the validators and sanitizers will now first determine the best type of the passed value and then apply the schema with that set type. In the case that a value could match multiple types, the schema of the first matching type will be used.

So, for instance, given the following schema, if the value 40 was submitted for the parameter, the user would receive param must be between 10 (inclusive) and 20 (inclusive) as an error message instead of param is not of type null,integer.

{
  "type": [ "null", "integer" ],
  "minimum": 10,
  "maximum": 20
}

Correct rest_sanitize_value_from_schema return type

The return type of rest_sanitize_value_from_schema has been corrected in [48307] to be mixed|WP_Error. Previously, the function had been documented as returning true|WP_Error.

Though WP_Error was a documented return type, it would not have been returned before WordPress 5.5. The function now returns a WP_Error if the value cannot be safely sanitized. For instance when checking the uniqueItems keyword.

New Keywords

WordPress 5.5 adds support for a number of JSON Schema keywords.

Pattern

The JSON Schema keyword pattern can be used to validate that a string field matches a regular expression.

For instance, given the following schema, #123 would be valid, but #abc would not.

{
  "type": "string",
  "pattern": "#[0-9]+"
}

The regex is not automatically anchored. Regex flags, for instance /i to make the match case insensitive are not supported. Developers are advised to use a constrained set of regex features so the schema can be interoperable between 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/. and PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher. The pattern should be valid according to the ECMA 262 regex dialect.

Relevant changeset: [47810].

Min and max string length

The minLength and maxLength keywords can be used to constrain the acceptable length of a string. Importantly multi-byte characters are counted as a single character and bounds are inclusive.

For instance, given the following schema, ab, abc, and abcd are valid, while a, and abcde are invalid.

{
  "type": "string",
  "minLength": 2,
  "maxLength": 4
}

The exclusiveMinimum and exclusiveMaximum keywords do not apply, they are only valid for numbers.

Relevant changeset: [47627].

Min and max array items

The minItems and maxItems keywords can be used to constrain the acceptable number of items included in an array.

For instance, given the following schema, [ 'a' ] and [ 'a', 'b' ] are valid, while [] and [ 'a', 'b', 'c' ] are invalid.

{
  "type": "array",
  "minItems": 1,
  "maxItems": 2,
  "items": {
    "type": "string"
  }
}

Again, the exclusiveMinimum and exclusiveMaximum keywords do not apply.

Relevante changeset: [47923].

Unique items

The uniqueItems keyword can be used to require that all items in an array are unique.

For instance, given the following schema, [ 'a', 'b' ] is valid, while [ 'a', 'a' ] is not.

{
  "type": "array",
  "uniqueItems": true,
  "items": {
    "type": "string"
  }
}

Uniqueness

Items of different types are considered unique, for instance, '1', 1 and 1.0 are different values.

When arrays are compared, the order of items matters. So the given array is considered to have all unique items.

[
  [ "a", "b" ],
  [ "b", "a" ]
]

When objects are compared, the order the members appear in does not matter. So the given array is considered to have duplicate items since the values are the same, they just appear in a different order.

[
  { 
    "a": 1,
    "b": 2
  },
  {
    "b": 2,
    "a": 1
  }
]

Uniqueness is checked in both rest_validate_value_from_schema and rest_sanitize_value_from_schema. This is to prevent instances where items would be considered unique before sanitization is applied, but after sanitization the items would converge to identical values.

Take for instance the following schema:

{
  "type": "array",
  "uniqueItems": true,
  "items": {
    "type": "string",
    "format": "uri"
  }
}

A request with [ "https://example.org/hello world", "https://example.org/hello%20world" ] would pass validation because the each string value is different. However, after esc_url_raw converted the space in the first url to %20 the values would be identical.

In this case rest_sanitize_value_from_schema would return an error. As such, developers are advised to always validate and sanitize parameters.

For more information, see #48821 on Trac.

Format Changes

A couple of changes have been made to handling of the format keyword.

Only validate the format keyword if the type is a string

Previously, implementing multi-type fields that had a format keyword required disabling the default validate & sanitize callbacks. After [48300] this can now be expressed entirely in JSON Schema.

For instance, given the following schema, a user can now submit both https://example.org/hello world and { "link": "https://example.org/hello world" } and validation & sanitization will be properly applied in both cases.

{
  "type": [ "string", "object" ],
  "properties": {
    "link": {
      "type": "string",
      "format": "uri"
    },
    "label": {
      "type": "string"
    }
  },
  "format": "uri"
}

For backward compatibility with invalid schemas the format validation will still apply if the type is not specified, or it is invalid.

Miscellaneous changes

  • The hex-color format has been introduced. This enforces a 3 or 6 hex digit color with a leading (see #49270).
  • The uuid format has been introduced. This enforces a uuid of any version using the wp_is_uuid function (see #50053).
  • The rest_validate_value_from_schema and rest_sanitize_value_from_schema functions will now issue _doing_it_wrong notices if the type keyword is missing or contains invalid values. The following types are valid: object, array, string, number, integer, boolean, and null (see #48821).
  • The following functions have been introduced to encapsulate type validation & sanitization: rest_is_integer, rest_is_array, rest_sanitize_array, rest_is_object and rest_sanitize_object (see #48821).

Props @desrosj, @davidbaumwald, and @justinahinon for reviewing.

#5-5, #dev-notes, #rest-api

Block Patterns in WordPress 5.5

In WordPress 5.5, the 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. editor introduces a new concept called block patterns. The goal is to allow users to build and share predefined block layouts, ready to insert and tweak more easily.

You can find the registered block patterns on the block inserter and add them to your post/page like any other block.

Block Patterns Registration

WordPress 5.5 comes with a number of built-in block patterns but it’s also possible for third-party plugins and themes to register additional block patterns or remove existing ones.

To register a custom block pattern, you can call the register_block_pattern function receives the name of the pattern as the first argument and an array describing properties of the pattern as the second argument. The properties of the block pattern include a title, a description, a categoryCategory The 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging., potentially some additional keywords, and the content of the pattern.

function my_plugin_register_block_patterns() {
	register_block_pattern(
		'my-plugin/my-awesome-pattern',
		array(
			'title'       => __( 'Two buttons', 'my-plugin' ),
			'description' => _x( 'Two horizontal buttons, the left button is filled in, and the right button is outlined.', 'Block pattern description', 'my-plugin' ),
			'categories'  => array( 'buttons' ),
			'content'     => "<!-- wp:buttons {\"align\":\"center\"} -->\n<div class=\"wp-block-buttons aligncenter\"><!-- wp:button {\"backgroundColor\":\"very-dark-gray\",\"borderRadius\":0} -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-background has-very-dark-gray-background-color no-border-radius\">" . esc_html__( 'Button One', 'my-plugin' ) . "</a></div>\n<!-- /wp:button -->\n\n<!-- wp:button {\"textColor\":\"very-dark-gray\",\"borderRadius\":0,\"className\":\"is-style-outline\"} -->\n<div class=\"wp-block-button is-style-outline\"><a class=\"wp-block-button__link has-text-color has-very-dark-gray-color no-border-radius\">" . esc_html__( 'Button Two', 'my-plugin' ) . "</a></div>\n<!-- /wp:button --></div>\n<!-- /wp:buttons -->",
		)
	);
}

add_action( 'init', 'my_plugin_register_block_patterns' );


It is also possible to register custom categories for your own block patterns.

Refer to the block patterns documentation for more details about these APIs.

CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. Block Patterns

While WordPress comes with a number of block patterns built-in, theme authors might want to opt-out of the bundled patterns and provide their own set.

You can do so by removing the core-block-patterns theme support flag.

remove_theme_support( 'core-block-patterns' );

#5-5, #block-editor, #dev-notes

Controlling Plugin and Theme auto-updates UI in WordPress 5.5

Site security is an integral part of modern websites. Keeping sites up to date by running the latest versions of WordPress, PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher, and any installed plugins or themes is highly recommended as an easy way to keep a site safe from any known security vulnerabilities.

By default, WordPress itself is configured to automatically update when new minor versions become available. While the code to auto-update plugins and themes has been in CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. for just as long, it’s seldom used by site owners because it requires the use of 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. hook.

This past February, a feature plugin was created in response to the 9 Projects for 2019/2020 to explore introducing a user interface that allows site administrators to easily manage 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 and theme auto-updates right from the dashboard. After 5 months of development on the GitHub repository, user feedback (the plugin was available on the WordPress.org plugin directory), testing (which includes over 1,000 active installs), and iterating by the contributors of the #core-auto-updates team, this feature pluginFeature Plugin A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins. was merged into Core in [47835] and will be released in WordPress 5.5.

A screenshot of a site’s Plugins page in the dashboard with the new “Automatic Updates” column (click to open this image in a new tab).

These new controls will allow website owners to keep their sites up-to-date and secure with less time and effort.

Note: Plugin and theme auto-updates are disabled by default. Administrators and site owners need to enable this feature to receive automatic plugin and theme updates. However, language packs for plugins and themes have always auto-updated when new updates are available. The new interface will not adjust language pack updates.

By default, all users with the update_plugins and update_themes capabilities are able to toggle auto-updates for plugins and themes respectively. On multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site installations, only networknetwork (versus site, blog) administrators have this capability, and only when in the context of the network dashboard.

A number of 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. are included for plugin authors and WordPress developers to customize the new feature to fit their needs. Let’s have a look at the available functions and hooks and how they can be used to tailor the plugin and theme auto-update experience.

New function: wp_is_auto_update_enabled_for_type()

This function indicates whether auto-updates are enabled for a given type. The two types accepted are theme and plugin.

// Check if auto-updates are enabled for plugins.
$plugin_auto_updates_enabled = wp_is_auto_update_enabled_for_type( 'plugin' );

Disable the auto-update user interface elements

It is possible to disable the new interface elements if desired. Returning false to the plugins_auto_update_enabled and themes_auto_update_enabled filters will disable the user interface elements for plugins and themes respectively. By default, these are enabled (true).

Note: This does not enable or disable auto-updates. It controls whether to show the user interface elements.

The following snippet will disable the plugin and theme auto-update UIUI User interface elements:

// Disable plugins auto-update UI elements.
add_filter( 'plugins_auto_update_enabled', '__return_false' );

// Disable themes auto-update UI elements.
add_filter( 'themes_auto_update_enabled', '__return_false' );

Modifying auto-update action links

Sometimes, a plugin or theme may want to manage updates on their own. This is common when they are not hosted on the WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ directories. For these instances, there are filters in place so plugin and theme authors can modify the auto-update related HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. output in certain locations.

Plugins screen: single site and multisite

With the plugin_auto_update_setting_html filter, it’s possible to filter auto-update column content, including the toggle links and time till next update attempt.

This filter pass the default generated HTML content of the auto-updates column for a plugin, with two additional parameters:

  • $plugin_file: The path to the main plugin file relative to the plugins directory.
  • $plugin_data: An array of plugin data.

For example, let’s say the “My plugin” plugin wants to prevent auto-updates from being toggled and its path relative to the plugins directory is my-plugin/my-plugin.php. The following example will change what is displayed within the auto-update column for that plugin:

function myplugin_auto_update_setting_html( $html, $plugin_file, $plugin_data ) {
	if ( 'my-plugin/my-plugin.php' === $plugin_file ) {
		$html = __( 'Auto-updates are not available for this plugin.', 'my-plugin' );
	}

	return $html;
}
add_filter( 'plugin_auto_update_setting_html', 'myplugin_auto_update_setting_html', 10, 3 );

Below is the result:

In the screenshot above, the default toggling action in the auto-updates column for one particular plugin has been modified using the previous example (click to open this image in a new tab).

For reference, here is the default HTML content:

<a href="…" class="toggle-auto-update" data-wp-action="…">
	<span class="dashicons dashicons-update spin hidden" aria-hidden="true"></span>
	<!-- The following text is replaced with "Disable auto-updates" when auto-updates are already enabled for this plugin -->
	<span class="label">Enable auto-updates</span>
</a>

Themes screen: single site only

Filtering the auto-update HTML content for Themes screen is a bit more tricky since this screen is rendered with a 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/. template. However, it is possible to hook into this screen using the theme_auto_update_setting_template filter and returning a modified $template (the rendering template used for every theme on the Themes page).

Note: since this template is used for each theme on the page, using a conditional statement to check for the theme being targeted is highly recommended. This can be done by utilizing the data.id JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. parameter (which contains the theme slug).

Full documentation about the properties available for the theme data object is available in wp_prepare_themes_for_js() DevHub page.

The following example will replace the text auto-update HTML content for the my-theme and twentytwenty themes:

function myplugin_auto_update_setting_template( $template ) {
	$text = __( 'Auto-updates are not available for this theme.', 'my-plugin' );

	return "<# if ( [ 'my-theme', 'twentytwenty' ].includes( data.id ) ) { #>
		<p>$text</p>
		<# } else { #>
		$template
		<# } #>";
}
add_filter( 'theme_auto_update_setting_template', 'myplugin_auto_update_setting_template' );

Below is the result:

In the screenshot above, the default toggling action for auto-updates has been modified using the previous example (click to open this image in a new tab).

For reference, here is the default template output:

<div class="theme-autoupdate">
	<# if ( data.autoupdate ) { #>
		<a href="{{{ data.actions.autoupdate }}}" class="toggle-auto-update" data-slug="{{ data.id }}" data-wp-action="disable">
			<span class="dashicons dashicons-update spin hidden" aria-hidden="true"></span>
			<span class="label">' . __( 'Disable auto-updates' ) . '</span>
		</a>
	<# } else { #>
		<a href="{{{ data.actions.autoupdate }}}" class="toggle-auto-update" data-slug="{{ data.id }}" data-wp-action="enable">
			<span class="dashicons dashicons-update spin hidden" aria-hidden="true"></span>
			<span class="label">' . __( 'Enable auto-updates' ) . '</span>
		</a>
	<# } #>
	<# if ( data.hasUpdate ) { #>
		<# if ( data.autoupdate ) { #>
			<span class="auto-update-time">
		<# } else { #>
			<span class="auto-update-time hidden">
		<# } #>
		<br />' . wp_get_auto_update_message() . '</span>
	<# } #>
	<div class="notice notice-error notice-alt inline hidden"><p></p></div>
</div>

Themes screen: multisite only

On multisite installs, the Themes screen can be modified in a way similar to the Plugins screen detailed above. Using the theme_auto_update_setting_html filter, the auto-update column content can be filtered, including the toggle links and time till next update.

This filter is passed the default generated HTML content of the auto-updates column for a theme with two additional parameters:

  • $stylesheet: The directory name of the theme (or slug).
  • $theme: The full WP_Theme object.

For example, let’s say the network administrator of a multisite network wants to disallow auto-updates for the Twenty Twenty theme. The following example will change what is displayed within the auto-update column for that theme:

function myplugin_theme_auto_update_setting_html( $html, $stylesheet, $theme ) {
	if ( 'twentytwenty' === $stylesheet ) {
		$html = __( 'Auto-updates are not available for this theme.', 'my-plugin' );
	}

	return $html;
}
add_filter( 'theme_auto_update_setting_html', 'myplugin_theme_auto_update_setting_html', 10, 3 );

Blanket auto-update opt-in

If a developer wants to enable auto-updates for all plugins and/or themes (including any that are installed in the future), the auto_update_plugin/auto_update_theme filters can be used.

// Enable all plugin auto-updates.
add_filter( 'auto_update_plugin', '__return_true' );

// Enable all theme auto-updates.
add_filter( 'auto_update_theme', '__return_true' );

Note: Any value returned using these filters will override all auto-update settings selected in the adminadmin (and super admin). Changes made using these filters also will not be reflected to the user in the interface. It is highly recommended to use these filters in combination with the hooks detailed above to inform the user of the auto-update policy being enforced.

This approach will not be appropriate for all sites. It’s recommended to use the new UI to manage auto-updates unless you’re sure blanket opting-in is right for your site.

Also note: This filter was added to the codebase in WordPress 3.7.0 and is likely being used to blanket enable auto-updates for plugins and themes on sites today. If it appears the new UI elements are not changing the auto-update behavior for plugins or themes on your site, this may be why. #50662 has been opened to notify site owners that this filter is being used in Site Health.


For information, refer to the following tickets on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.: #50052, #50280.

This post is the first part of the plugins and themes auto-updates dev notesdev note Each important change in WordPress Core is documented in a developers note, (usually called dev note). Good dev notes generally include a description of the change, the decision that led to this change, and a description of how developers are supposed to work with that change. Dev notes are published on Make/Core blog during the beta phase of WordPress release cycle. Publishing dev notes is particularly important when plugin/theme authors and WordPress developers need to be aware of those changes.In general, all dev notes are compiled into a Field Guide at the beginning of the release candidate phase. for WordPress 5.5.

Thanks @desrosj and @pbiron for technical review and proofreading.

#5-5, #auto-update, #auto-updates, #dev-notes, #feature-plugins, #feature-projects, #feature-autoupdates

Dashicons in WordPress 5.5 (the final update)

Edit 8/12/2020: When initially published, 5 editor icons were missing. These have been added and all counts have been updated to be accurate. Props @coffee2code.

Earlier this year, a post was published on the Make WordPress Design blogblog (versus network, site) detailing the short road ahead for Dashicons.

We’ve recently discussed how to best move forward with icons in WordPress. The 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. editor uses SVG icons directly, and the rest of WordPress uses the Dahsicons icon font. One of the challenges with an icon font is that it’s one big compiled “sprite”, and so even though it gets cached well, for every icon you add the sprite grows bigger. With SVG you include just the icons you need.

@joen – Next steps for Dashicons

Dashicons were originally brought into CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. as part of the MP6 project that redesigned the entire WordPress adminadmin (and super admin) (see #25858). A lot has changed over the last 7+ years and it’s time to explore better, more efficient ways to manage icons in WordPress Core.

This update will be the final update to the Dashicons icon font in WordPress Core.

Don’t worry, the Dashicons font is not going anywhere. It will continue to be bundled with WordPress in future releases. However, requests to add new icons to the font will no longer be accepted.

New icons

In the final Dashicons update being included in the 5.5 release, 71 new icons have been added. This includes 32 icons that were merged into the icon font that already existed in the block editor.

Reminder: The WOFF 1.0 format (while still included for backwards compatibility) will not include these new icons. The reasons for this were detailed in the Dashicons developer note accompanying WordPress 5.2.

Block editor

IconCSSCSS Cascading Style Sheets. ClassCode
dashicons-align-full-width f114
dashicons-align-pull-left f10a
dashicons-align-pull-right f10b
dashicons-align-wide f11b
dashicons-block-default f12b
dashicons-button f11a
dashicons-cloud-saved f137
dashicons-cloud-upload f13b
dashicons-columns f13c
dashicons-cover-image f13d
dashicons-ellipsis f11c
dashicons-embed-audio f13e
dashicons-embed-generic f13f
dashicons-embed-photo f144
dashicons-embed-post f146
dashicons-embed-video f149
dashicons-exit f14a
dashicons-heading f10e
dashicons-html f14b
dashicons-info-outline f14c
dashicons-insert-after f14d
dashicons-insert-before f14e
dashicons-insert f10f
dashicons-remove f14f
dashicons-shortcode f150
dashicons-table-col-after f151
dashicons-table-col-before f152
dashicons-table-col-delete f15a
dashicons-table-row-after f15b
dashicons-table-row-before f15c
dashicons-table-row-delete f15d
dashicons-saved f15e

Social

IconCSS ClassCode
dashicons-amazon f162
dashicons-google f18b
dashicons-linkedin f18d
dashicons-pinterest f192
dashicons-podio f19c
dashicons-reddit f195
dashicons-spotify f196
dashicons-twitch f199
dashicons-whatsapp f19a
dashicons-xing f19d
dashicons-youtube f19b

Databases

IconCSS ClassCode
dashicons-database-add f170
dashicons-database-export f17a
dashicons-database-import f17b
dashicons-database-remove f17c
dashicons-database-view f17d
dashicons-database f17e

Notifications

IconCSS ClassCode
dashicons-bell f16d

Transportation

IconCSS ClassCode
dashicons-airplane f15f
dashicons-car f16b

Devices

IconCSS ClassCode
dashicons-calculator f16e
dasicons-games f18a
dashicons-printer f193

Food & beverage

IconCSS ClassCode
dashicons-beer f16c
dashicons-coffee f16f
dashicons-drumstick f17f
dashicons-food f187

Miscellaneous

IconCSS ClassCode
dashicons-bank f16a
dashicons-hourglass f18c
dashicons-money-alt f18e
dashicons-open-folder f18f
dashicons-pdf f190
dashicons-pets f191
dashicons-privacy f194
dashicons-superhero f198
dashicons-superhero-alt f197
dashicons-edit-page f186
dashicons-fullscreen-alt f188
dashicons-fullscreen-exit-alt f189

Thank you to anyone and everyone that has contributed to Dashicons over the last 7+ years.


To see all of the changes to Dashicons since the last update included in WordPress 5.2, check out the repository on GitHub or the ticketticket Created for both bug reports and feature development on the bug tracker. on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. (#49913). To get a complete overview of all icons please visit developer.wordpress.org/resource/dashicons/.

Props @empireoflight, @joen, and @casiepa for proofreading.

#5-5, #dashicons, #dev-notes, #ui

Register theme feature API

Themes use the add_theme_support 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. to declare support for a particular theme feature. For instance, add_theme_support( 'align-wide' ) declares that a theme supports the wide alignment feature.

When the Themes 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/. controller was introduced in WordPress 5.0 , a minimal set of theme features were exposed (see #45016). In WordPress 5.4, this was expanded to all WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. theme features (see #49037). Support for custom theme features was not included because there was not a safe way to validate their shape and ensure the associated data was not private.

In [48171] the new register_theme_feature() API was introduced to declare the format of a theme feature. This does not indicate that the current theme supports that feature, merely that it is available to be supported.

Features that are registered with show_in_rest enabled will have the add_theme_support() value exposed in the REST API themes endpoint. This allows for 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 developers to access the theme support values over the REST API. Currently, the REST API is the only consumer of the registered theme features.

WordPress Core registers the list of built-in theme features in the create_initial_theme_features() function.

The API

The register_theme_feature() function takes two arguments. The first, $feature, is the name uniquely identifying the feature. The second, $args, is a list of arguments detailing the feature. If the feature is successfully registered, the function will return true. Otherwise, a WP_Error instance is returned.

Type

The type argument specifies the JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. Schema type of the value that should be passed to add_theme_support(). The acceptable values are string, boolean, integer, number, object and array.

The object type refers to a PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher associative array (an array of key, value pairs). The array type refers to a PHP numerical array, in other words a list of values without specific keys.

Variadic

The variadic argument specifies whether the feature utilizes the variadic argument support of add_theme_support(), or if the feature is entirely described by the first argument. Theme features in Core aren’t variadic.

add_theme_support( 'html5', array(
	'search-form',
	'comment-form',
) );

If the html5 feature was variadic, add_theme_support() would be used like this.

add_theme_support( 'html5', 'search-form', 'comment-form' );

Description

The description argument is meant to be a short description of the feature intended for developers. The REST API surfaces this description in the schema for the Themes API.

Show in REST

By default, theme features are not included in the REST API. To opt-in to this behavior, the show_in_rest flag can be set to true or an array with additional arguments to describe the feature.

Schema

The show_in_rest.schema argument specifies the JSON schema describing the format of the feature. If the feature type is an object or array specifying a schema is mandatory.

For an array type, the schema should contain an items definition that describes the format of each entry in the array. For example, the html5 theme feature is described with the following schema.

array(
	'items' => array(
		'type' => 'string',
		'enum' => array(
			'search-form',
			'comment-form',
			'comment-list',
			'gallery',
			'caption',
			'script',
			'style',
		),
	),
)

For an object type, the schema should define each of the properties of the object that should appear in the REST API. This isn’t always every field that can be registered. For instance, the custom-header omits the various callback flags because they aren’t safe to include in the REST API.

array(
	'properties' => array(
		'default-image'      => array(
			'type'   => 'string',
			'format' => 'uri',
		),
		'random-default'     => array(
			'type' => 'boolean',
		),
		'width'              => array(
			'type' => 'integer',
		),
		'height'             => array(
			'type' => 'integer',
		),
		'flex-height'        => array(
			'type' => 'boolean',
		),
		'flex-width'         => array(
			'type' => 'boolean',
		),
		'default-text-color' => array(
			'type' => 'string',
		),
		'header-text'        => array(
			'type' => 'boolean',
		),
		'uploads'            => array(
			'type' => 'boolean',
		),
		'video'              => array(
			'type' => 'boolean',
		),
	),
)
Default

The show_in_rest.schema.default argument can be used to specify an alternate default value to be shown in the REST API if the current theme does not support the registered feature. By default, the feature will have a value of false. The post-formats feature declares a default of [ 'standard' ].

Name

The show_in_rest.name argument can be used to specify an alternate property name for the feature when it is displayed in the REST API. For example, the post-formats feature declares a name of formats.

Prepare callback

The show_in_rest.prepare_callback argument can be used to customize how the feature is formatted in the REST API. By default, the REST API sanitizes the raw value from get_theme_support according to the specified schema.

The post-formats feature uses a custom prepare_callback to ensure that standard is always included as a supported post format.

function ( $formats ) {
	$formats = is_array( $formats ) ? array_values( $formats[0] ) : array();
	$formats = array_merge( array( 'standard' ), $formats );

	return $formats;
}

The prepare_callback function receives the following parameters.

  1. The raw feature value from add_theme_support().
  2. The args describing the feature from register_theme_feature().
  3. The feature name.
  4. The WP_REST_Request object being responded to by the REST API.

Example

This example registers the editor-color-palette theme feature. Theme features should be registered on the setup_theme action.

function myplugin_setup_theme() {
	register_theme_feature( 'editor-color-palette', array(
		'type'         => 'array',
		'description'  => __( 'Custom color palette if defined by the theme.' ),
		'show_in_rest' => array(
			'schema' => array(
				'items' => array(
					'type'       => 'object',
					'properties' => array(
						'name'  => array(
							'type' => 'string',
						),
						'slug'  => array(
							'type' => 'string',
						),
						'color' => array(
							'type' => 'string',
						),
					),
				),
			),
		),
	) );
}
add_action( 'setup_theme', 'myplugin_setup_theme' );

For more information, refer to the related ticketticket Created for both bug reports and feature development on the bug tracker. on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. (#49406).

Props @desrosj and @justinahinon for reviewing.

#5-5, #dev-notes, #rest-api, #themes