Registering default values for meta data

With WordPress 5.5, the register_meta() functions ( including register_post_meta() ) now support registering default values. Previously it was only possible to register default values for 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/. schema like this:

register_meta(
     'post',
     'greeting',
     array(
         'single'       => true,
         'type'         => 'string',
         'show_in_rest' => array(
             'schema' => array(
                 'type'  => 'string',
                 'default' => 'hello',
             ),
         ),
     )
 );

However, this would only be applied to calls made from within the REST API – calls to get_post_meta() would not use this default value. Now it is possible to pass in a default value that will be applied to all calls to any of the 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. functions, like this:

register_meta(
     'post',
     'greeting',
     array(
         'single'       => true,
         'type'         => 'string',
         'default'      => 'hello',
         'show_in_rest' => array(
             'schema' => array(
                 'type'  => 'string',
             ),
         ),
     )
 );

This brings register_meta() inline with register_setting() where it has been possible to register default values for options since WordPress 4.7.

Default values can also be paired with object sub types (introduced in WordPress 4.9.8) to limit the scope of a default value. An example of this might be if 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 registers a custom post typeCustom Post Type WordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. of product. A developer could register a default value that would only apply to the post of type product.

register_post_meta(
     'product',
     'price',
     array(
         'single'       => true,
         'type'         => 'string',
         'default'      => '0.00',
     )
 );

It is worth noting that registering a default value to a custom post type like this may have some performance overhead. To determine which post type the current post ID is, it has to load that object. See get_object_subtype for more detail. In most cases, the meta and main objects are loaded at the same time (like when using WP_Query) but if your code is doing something other than just loading meta data, it may now load the main object type too.

Non-Single Metadata

It is also possible to register not-single default values like this:

register_post_meta(
     'product',
     'price',
     array(
         'single'       => false,
         'type'         => 'string',
         'default'      => '0.00',
     )
 );

When requesting multiple values, like this:

$result = get_post_meta( 123, 'price', false );

The above code will return a numeric array with 0.00, as the first value.

Validation

When registering a default meta value the data must match the type provided. The following example will trigger a _doing_it_wrong notice as hello is not an integer.

register_meta(
     'post',
     'greeting',
     array(
         'single'       => true,
         'type'         => 'integer',
         'default'      => 'hello',
     )
 );

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

If you desire to do some really custom with default meta values, there is now a filter:

$value = apply_filters( "default_{$meta_type}_metadata", $value, $object_id, $meta_key, $single, $meta_type );

This is a dynamic filter, requiring you to add the meta type. This is an example of it’s use:

function add_my_meta_value( $value, $object_id, $meta_key, $single ){
	if( 'price' === $meta_key ) {
		if ( ! $single ) {
	   		$value = array( '0.99' );
		} else {
			$value = '0.99';
		}
	}
}
add_filter( 'default_post_metadata', 'add_my_meta_value', 10, 4 );

New functions

To make this functionality possible there are two new functions added to WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.:

  • get_metadata_raw()
  • get_metadata_default()

Now the get_metadata() function calls get_metadata_raw() and if the value is null, calls get_metadata_default(). So calling get_metadata() no longer gets the raw value, that is what get_metadata_raw() is now intended for.

More detail of the history of this change can be found in the original tracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. #43941.

Props @timothyblynjacobs, @jjj and @justinahinon for reviewing prior to publish.

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

REST API changes in WordPress 5.5

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/. will see a lot of changes in WordPress 5.5. In an effort to explain each change adequately, a number of these were split out and covered by other 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..

Below are some other noteworthy changes that deserve a call out.

Discoverable REST resource links

To aid automated and human discovery of the REST API, a link was added in the <head> of the document and as a Link 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. to the REST route for the currently queried document in [48273].

For example, in the <head> of this post, the following <link> appears.

<link rel="alternate" type="application/json" href="https://make.wordpress.org/core/wp-json/wp/v2/posts/82428">

Links are added for post, pages, and other custom post types, as well as terms and author pages. Links are not currently output for post archives or search results.

See #49116 for more information.

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.

Three new functions are introduced.

  • rest_get_route_for_post() retrieves the route for the given post. For instance, /wp/v2/posts/1.
  • rest_get_route_for_term() retrieves the route for the given term. For instance, /wp/v2/tags/1.
  • rest_get_queried_resource_route() retrieves the route for the currently queried resource. For instance, /wp/v2/users/1 when on the author page for the user with ID of 1.

All three functions return an empty string if a REST API route cannot be determined. To convert the route to a link, pass the result to the rest_url() function.

For more information, see #49116.

Customization

For custom post types, only routes using the built-in WP_REST_Posts_Controller controller class will work by default. For custom controllers, the rest_route_for_post 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. can be used to supply the correct route.

function my_plugin_rest_route_for_post( $route, $post ) {
	if ( $post->post_type === 'my-cpt' ) {
		$route = '/wp/v2/my-cpt/' . $post->ID;
	}

	return $route;
}
add_filter( 'rest_route_for_post', 'my_plugin_rest_route_for_post', 10, 2 );

Similar logic applies to taxonomies, only the built in WP_REST_Terms_Controller is supported by default. The rest_route_for_term filter can be used for custom controller classes.

function my_plugin_rest_route_for_term( $route, $term ) {
	if ( $term->taxonomy === 'my-tax' ) {
		$route = '/wp/v2/my-tax/' . $term->term_id;
	}

	return $route;
}
add_filter( 'rest_route_for_term', 'my_plugin_rest_route_for_term', 10, 2 );

The rest_get_queried_resource_route() function is filterable to allow for identification of custom resources.

function my_plugin_rest_queried_resource_route( $route ) {
	$id = get_query_var( 'my-route' );
	if ( ! $route && $id ) {
		$route = '/my-ns/v1/items/' . $id;
	}

	return $route;
}
add_filter( 'rest_queried_resource_route', 'my_plugin_rest_queried_resource_route' );

These links are output using the existing rest_output_link_wp_head and rest_output_link_header functions. As such, if API discovery has already been disabled, these links will not be rendered.

For more information, see #49116.

CORS changes

In [48112], the Link header was added to the list of exposed CORS response headers. Previously, only the X-WP-Total and X-WP-TotalPages headers were exposed which means that clients would have to manually construct the URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org to implement pagination instead of using the prev and next Links.

In [48452], the Content-Disposition, Content-MD5 and X-WP-Nonce were added to the list of allowed cors request headers. The Content-Disposition and Content-MD5 headers allow for easier file uploading across domains by using a File/Blob object directly. The X-WP-Nonce header is allowed for making authenticated cross-origin and same-origin requests consistently.

Two filters are introduced, rest_exposed_cors_headers and rest_allowed_cors_headers to simplify the process of plugins modifying the list of cors headers.

For more information, see #50369 and #41696.

Miscellaneous

Warn when omitting a permission_callback

The REST API treats routes without a permission_callback as public. Because this happens without any warning to the user, if the permission callback is unintentionally omitted or misspelled, the endpoint can end up being available to the public. Such a scenario has happened multiple times in the wild, and the results can be catastrophic when it occurs.

In [48526] a _doing_it_wrong notice has been added when a permission callback is omitted. For REST API routes that are intended to be public, it is recommended to set the permission callback to the __return_true built in function.

So for instance, this route registration will cause the following warning to appear.

register_rest_route(
	'my-ns',
	'echo',
	array(
		'methods'  => WP_REST_Server::EDITABLE,
		'callback' => function ( WP_REST_Request $request ) {
			return new WP_REST_Response( $request->get_param( 'echo' ) );
		},
	)
);
The REST API route definition for my-ns/echo is missing the required permission_callback argument. For REST API routes that are intended to be public, use __return_true as the permission callback.

If it was intended for this endpoint to be public, you could fix it like this.

register_rest_route(
	'my-ns',
	'echo',
	array(
		'methods'  => WP_REST_Server::EDITABLE,
		'callback' => function ( WP_REST_Request $request ) {
			return new WP_REST_Response( $request->get_param( 'echo' ) );
		},
		'permission_callback' => '__return_true',
	)
);

If you wanted to check the user’s capabilities, you could do it like this.

register_rest_route(
	'my-ns',
	'echo',
	array(
		'methods'  => WP_REST_Server::EDITABLE,
		'callback' => function ( WP_REST_Request $request ) {
			return new WP_REST_Response( $request->get_param( 'echo' ) );
		},
		'permission_callback' => function( WP_REST_Request $request ) {
			return current_user_can( 'manage_options' );
		},
	)
);

For more information, see #50075.

Using wp_send_json() is doing it wrong

When building a REST API route, it is important for the route callback (and permission_callback) to return data instead of directly sending it to the browser. This ensures that the additional processing that the REST API server does, like handling linking/embedding, sending headers, etc… takes place.

// This is incorrect.
echo wp_json_encode( $data );
die;

// And this.
wp_send_json( $data );

// And this.
wp_send_json_error( 'My Error' );

// Instead do this.
return new WP_REST_Response( $data );

// Or this.
return new WP_Error( 'my_error_code', 'My Error Message' );

After [48361], a _doing_it_wrong notice is now issued when any of the wp_send_json family of functions are used during a REST API request.

For more information, see #36271.

Preloading silenced deprecation errors

When using rest_preload_api_request any deprecation errors encountered when processing the request were silenced because the REST API handling took over as soon as the API server was booted.

After [48150], the REST API handling will only apply for actual REST API requests.

For more information, see #50318.

Props @desrosj and @justinahinon for proofreading.

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

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

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

Shipping Experimental Endpoints in Core: REST API Meeting Summary June 11, 2020

This post summarizes the #core-restapi meeting for Thursday June 11, 2020. The focus of this meeting was discussing the possibility of shipping __experimental 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/. routes in WordPress CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.. Read the Slack archive, account required.

Background

Part of the REST API team’s role is to help ensure that enhancements to the REST API follow Core’s established patterns and that the interface is sufficiently forward compatible.

The Problem

WordPress 5.5 is shaping up to have a number of new and improved REST API endpoints to support the latest GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ features: #40878 and #50244 for Navigation, #50321 and #48654 for 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. Directory, #47620 for Block Registration, etc…

Another Gutenberg feature currently slated for 5.5 is Image Editing. This feature utilizes the REST API and existing WP_Image_Editor 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 persist the image edits. This feature took the REST API team a bit off guard, and the team is worried about providing an adequate review of the feature in time for WordPress 5.5 given the other tickets in progress.

This feature is currently listed as a Gutenberg Experiment. The hope is to promote it from an experiment by the next Gutenberg release.

Potential Solution

While the current server side code supporting Image Editing requires changes, it is likely that the Editor and/or Media team will be able to resolve these issues in time for BetaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. 1. The question then becomes if the REST API team will have the bandwidth to do a review. Additionally, will the API have had a long enough soak time to reduce the possibility of a design error necessitating a breaking change.

In the weekly #core-editor meeting, the possibility of including the required REST API endpoints in the __experimental namespace was briefly discussed. This would allow us to ship the Image Editing feature in WordPress 5.5. If breaking API changes were necessitated those could be made when the endpoint is promoted to the wp/v2 endpoint.

Note: This is distinct from the feature being marked as an “experiment” in the Gutenberg settings page. The goal is to ship this as a feature in WordPress 5.5; the Gutenberg 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 would not be required to use the feature.

Experimental APIs

Nearly all APIs in WordPress are “public” and backwards compatibility is maintained. Some APIs are explicitly marked as @access private, most notably the List Table API. Despite being private, when responsive list tables (#32395) were introduced, great lengths were made to ensure that the changes were backwards compatible with custom list tables.

Gutenberg introduced the idea of “experimental” and “unstable” APIs.

There is no support commitment for experimental and unstable APIs. They can and will be removed or changed without advance warning, including as part of a minor or patchpatch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing. release. As an external consumer, you should avoid these APIs.

An experimental API is one which is planned for eventual public availability, but is subject to further experimentation, testing, and discussion.
An unstable API is one which serves as a means to an end. It is not desired to ever be converted into a public API.

The Gutenberg Coding Guidlines

The version of Gutenberg that ships with WordPress Core utilizes a number of __experimental and __unstable APIs. But so far this has been limited to only 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/. APIs.

REST API endpoints introduced in the Gutenberg plugin are currently introduced in the __experimental namespace, but are transitioned to wp/v2 before being merged to WordPress Core. Because the namespace changes, this process in itself is breaking, even if no other API changes were made.

Discussion

Editorial Note: Part of this discussion focused on the current state of the endpoint which has a number of functional and design issues. These have been flagged in the various issues and tickets and I won’t be summarizing these issues here. We would not ship an endpoint in WordPress Core, even as a proposed __experimental one, if it was broken.

@timothyblynjacobs main concern is that if there are security issues with the endpoint, or any other “fatal flaws” it being __experimental doesn’t protect us in anyway.

@spacedmonkey is concerned that once a feature is in Core, developers will start using it and it can never be removed. WordPress hasn’t shipped features in Core before they are ready and shipping an __experimental endpoint like this would break that pattern. If the feature isn’t ready, we should wait until 5.6.

@earnjam thinks that if it’s something useful, people will use it regardless of any flag/prefix applied. Then it’s a question of if we’re comfortable breaking stuff because we warned them.

To me the insistence on full backward compatibility is one of WP’s biggest assets. We’ve been drifting away from that to an extent in Gutenberg and I think it undermines a core element of what makes WordPress what it is. I think in core we had moved away from shipping private APIs for a while for this very reason, they’re going to get used whether we want them to or not. To me, that’s the whole point of doing feature plugins. It allows you to iterate and break things in the plugin, but not core. IMO the Gutenberg plugin is an experimental flag. Only the stuff that is truly ready should be brought over.

I’m ok with the experimental stuff in the Gutenberg plugin because that is opting in. I don’t know that I’m comfortable with it in core.

From @earnjam.

@jamesburke asked if the __experimental approach been a success with Gutenberg? If so, it’d be a useful pattern to implement (regardless of whether the editing endpoint is ready for this).

IMO, if you mark it as experimental, then break whatever needs to get broken. I’ve worked on production projects that heavily utilize Gutenberg experimental functionality, and it’s always nice to have early access to things. In my experience, the opportunity to use functionality in the wild and apply it to real world problems greatly outweighs the attention/effort needed to upgrade if/when something breaks on the experiment. 

From @jamesburke.

@carike points out that lot of non-technical users won’t even know that the feature exists and are not in the same position to mitigate the associated risks – particularly in use cases that are not traditional publishing, e.g. e-commerce.

@chrisvanpatten thinks that more experimentation is absolutely a good thing, but is not sure Core is the right venue for that. Gutenberg is able to play a bit fast and loose with backwards compatibility, but that has been isolated from Core to a degree. He tends to believe that __experimental APIs landing in Core has been a mistake, even as someone who has leveraged experimental JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. APIs before.

@ajlende thinks there have been good arguments for holding off too. When he pushed the initial image editing feature, the intention was for people to start trying it out to let people use it and adjust. If Core is looking for more stable things, then he’d agree it isn’t ready.

@joemcgill mentioned that if the API is shipping in Core, even as __experimental, it absolutely will get used, so backwards compatibility must be a consideration.

@sageshilling suggested offering a quick way to turn it off the feature for sites that don’t want the image editing options. @ajlende indicated that the current code is behind a feature flag. Supporting an opt-out if the feature was included in Core would therefore likely be possible.

Next Steps

@joemcgill is fully +1 on the existence of a REST API replacement to the AJAX callbacks currently in core which is used by the image editor in the media modal and is happy to help this if it’s a priority.

@mikeschroder is completely agreed that a REST API endpoint to replace the existing AJAX is awesome.

Tickets/Issues

#49096, #44405. GB-22959, GB-21024, GB-22579.

Questions

This post is a solicitation for feedback as much as a meeting summary. Some potential questions to ponder.

  1. Have experimental APIs been a success in Gutenberg? How often are __experimental APIs transitioned to stable APIs? Is this a fast process, or do the APIs stay as __experimental for a long time? What sort of changes are discovered that necessitate breaking changes?
  2. Should we be comfortable breaking backwards compatibility because developers were explicitly warned that the feature was an experiment?

The next REST API meeting is this Thursday June 18th at 18:00 UTC.

#5-5, #gutenberg, #rest-api

REST API Meeting Agenda for May 21

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/. weekly component chat will occur this week at May 21, 2020 18:00 UTC in the #core-restapi SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel.

Agenda Items:

  • Menus 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. Batch Requests
  • Authentication Update
  • 5.5 Updates
  • Open Floor

All agenda items are welcome, from all teams and contributors; please post them as comments below or let us know by joining the meeting.

#agenda, #rest-api

REST API: Decision on Introducing a dashboard namespace

In Introduce a dashboard namespace 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/. team proposed introducing a dashboard namespace to house dashboard specific endpoints like Site Health and the 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.. Based on the feedback received on the post, as well as in the #core-restapi slackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel, the REST API team has decided on giving major features their own namespace. For example, wp-site-health and wp-customize.

Many contributors felt that relegating these endpoints to a dashboard namespace did a disservice to the features and made them harder to discover. Additionally, it may suggest to third-party developers that these endpoints are strictly internal, even though the endpoints would be useful outside of WP-Adminadmin (and super admin).

The wp/$FEATURE/v1 pattern was suggested a number of times. However, using a wp-$FEATURE prefix allows us to maintain the recommended pattern of <prefix>/v<version>.

Namespaces are prefixed with wp so that 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 don’t have to worry that any namespace they pick could eventually be reappropriated by WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress..

For any future smaller endpoints that don’t need their own dedicated namespace, for instance Community Events, they’ll use the dashboard/v1 pattern.

#rest-api

REST API Meeting Agenda for March 12

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/. weekly component chat will occur this week at March 12, 2020 18:00 UTC in the #core-restapi SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel.

Please note: We have not changed the UTC time for this meeting. If your country has recently adjusted for daylight savings time, this may be a different hour than the past few months.

Agenda Items:

  • Discuss priorities for the 5.5 development cycle
  • Discuss 5.4 documentation updates
  • Open Floor

All agenda items are welcome, from all teams and contributors; please post them as comments below or let us know by joining the meeting.

#agenda, #rest-api

REST API Changes in 5.4

TaxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. “OR” Relation Now Supported in Posts Controller

Querying for /wp/v2/posts?tags=1&categories=2 returns all posts assigned 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.) with ID 1, AND assigned the categoryCategory The 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging. with ID 2. This AND relationship, where multiple taxonomies’ term relationships must all be satisfied, has been the only supported behavior in these collection endpoints since WordPress 4.7.

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/. /wp/v2/posts endpoint, as well as custom post typeCustom Post Type WordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. endpoints extending from WP_REST_Posts_Controller (including custom post types specifying "show_in_rest" => true), now supports a new tax_relation parameter which can be used to return posts matching either taxonomy 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., rather than both.

As an example, in WordPress 5.4, the posts endpoint query

/wp/v2/posts?tags=1&categories=2&tax_relation=OR

will now return posts in either the tag ID 1 or the category with ID 2.

Selective Link Embedding

The REST API now supports returning a limited set of embedded objects using the _embed parameter. As an example, in WordPress 5.4, the following query only embeds the author information instead of including all the comments, media, etc…

/wp/v2/posts/?_embed=author

All embeds will be returned if a value for the _embed parameter is omitted, or set to true or 1.

WP_REST_Server method changes

WordPress 5.4 changes the signature of two methods in the WP_REST_Server class. Developers who are extending WP_REST_Server and overriding these methods should update their code to match the new signatures to avoid PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher warnings.

  1. The signature of WP_REST_Server::embed_links() is now embed_links( $data, $embed = true ). The new $embed paramter accepts an array of link relations (such as array( 'author', 'wp:term' )) and limits the embedded links in the response to those relations. The default of true maintains the previous behavior of embedding all links in the response. For more details, see #39696.
  2. The signature of WP_REST_Server::get_routes() is now get_routes( $namespace = '' ). The new $namespace parameter accepts a string and limits the returned routes to those whose namespace matches the string. Internally, WP_REST_Server uses this new parameter to improve the performance of WP_REST_Server::dispatch() by reducing the number of regex checks necessary to match a request to a registered route. For more details, see #48530.

For performance reasons, WP_REST_Server::embed_links() also now caches response data in memory. This cache is managed by WP_REST_Server::response_to_data(). Code calling the protected embed_links method being called directly may need to be updated to ensure stale data is not returned.

(Thank you to @dlh for authoring this section)

See the full list of REST API changes on TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress..

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