The WordPress coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. development team builds WordPress! Follow this site for general updates, status reports, and the occasional code debate. There’s lots of ways to contribute:
Found a bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority.?Create a ticket in the bug tracker.
WordPress 7.1 extends wp_get_abilities() with a standard way to filterFilterFilters 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. registered abilities.
The function now accepts an optional $args array that can filter abilities by category, namespace, or metadata. It also supports callbacks for custom per-item filtering and final result processing.
Two new WordPress filters allow plugins to influence ability retrieval across the site:
wp_get_abilities_item_include
wp_get_abilities_result
The REST APIREST APIThe 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/’s abilities list controller now uses wp_get_abilities() instead of implementing categoryCategoryThe 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging. filtering separately. It also supports filtering abilities by namespace.
Why was this change needed?
Before WordPress 7.1, there were two ways to retrieve abilities:
// Retrieve every registered ability.
$abilities = wp_get_abilities();
// Retrieve one named ability.
$ability = wp_get_ability( 'my-plugin/export-users' );
wp_get_abilities() always returned the complete registry. A caller needing a subset had to retrieve every ability and filter the result manually:
Several consumers developed their own versions of this pattern for category, namespace, and metadata checks. The REST abilities controller also performed its own category filtering after retrieving the complete registry.
This led to:
Duplicated filtering code.
Inconsistent filtering semantics between consumers.
Different behaviour between the PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher and REST APIs.
No standard extension points for ability selection.
Additional filtering passes over the registry.
WordPress 7.1 moves this work into wp_get_abilities(), providing one shared filtering pipeline for CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. and plugins.
An ability such as my-plugin/export-users matches, while another-plugin/export-users does not.
Namespace matching includes the namespace delimiter. Passing my-plugin does not accidentally match an ability registered under a similarly named my-plugin-extra namespace.
Filtering by metadata
The meta argument selects abilities whose metadata contains the specified key-value pairs:
Metadata comparisons are strict. The value true does not match 1, and false does not match 0.
The metadata filter checks that every requested condition exists and matches. An ability may contain additional metadata that was not included in the query.
Combining declarative filters
The category, namespace, and meta arguments can be combined:
The result callback runs after all per-item matching has completed. It is suitable for:
Sorting.
Slicing or pagination.
Reordering.
Other final result transformations.
Like item_include_callback, result_callback applies only to the current function call.
Registered abilities are normally returned in an associative array keyed by ability name. When sorting or slicing the result, preserve those keys when downstream code depends on them.
New global filters
WordPress 7.1 also introduces two filters for plugins that need to affect ability retrieval beyond a single call site.
wp_get_abilities_item_include
The wp_get_abilities_item_include filter runs for every ability that passed the declarative conditions and the caller’s item_include_callback:
$include: Whether the ability should currently be included.
$ability: The ability being evaluated.
$args: The complete arguments passed to wp_get_abilities().
Because declarative mismatches are removed before this filter runs, the filter cannot add an ability that failed category, namespace, or meta matching. It can influence the inclusion of abilities that have reached this stage, as well as their global exclusion.
wp_get_abilities_result
The wp_get_abilities_result filter receives the complete result after the caller’s result_callback:
add_filter(
'wp_get_abilities_result',
function ( array $abilities, array $args ): array {
// Apply site-wide result processing when appropriate.
return $abilities;
},
10,
2
);
The filter receives:
$abilities: The final matched array.
$args: The complete arguments passed to wp_get_abilities().
It can be used for site-wide sorting, reordering, or other final processing.
These are global filters. Plugins should use them only when the behaviour is intended to affect every relevant caller. For logic that belongs to one operation, prefer item_include_callback or result_callback.
Filtering order
The complete pipeline runs in the following order:
Match the category argument.
Match the namespace argument.
Match the meta argument.
Run item_include_callback.
Apply wp_get_abilities_item_include.
Add included abilities to the matched result.
Run result_callback on the complete result.
Apply wp_get_abilities_result.
The declarative checks, item callback, and item filter run within a single pass over the registry.
This avoids the separate array_filter() passes that consumers previously had to implement.
Discovery over REST
The REST collection endpoint delegates to wp_get_abilities() and exposes the declarative filters as query parameters:
GET /wp-json/wp-abilities/v1/abilities?namespace=my-plugin
GET /wp-json/wp-abilities/v1/abilities?category=my-plugin-content
GET /wp-json/wp-abilities/v1/abilities?meta[annotations][readonly]=true
Parameters can be combined and use the same AND logic.
?category=data-export&namespace=my-plugin
Every collection request also forces meta.show_in_rest = true internally. Supplying another metadata query can’t reveal an ability that is hidden from REST. The endpoint still requires an authenticated WordPress user, and executing a listed ability still requires its permission callback to pass.
Custom metadata needs a REST parameter schema if its query-string values should be coerced before strict comparison. Without one, 'true' will never match boolean true. The rest_abilities_collection_params filter extends the collection argument schema:
After that declaration, the REST API casts "true" to a boolean true before the value reaches the metadata-matching logic.
GET /wp-json/wp-abilities/v1/abilities?meta[my_plugin][enabled]=true
Built-in annotation types
The known readonly, destructive, and idempotent annotation values are coerced from query strings to boolean values before strict matching. Core declares the schema for these standard ability annotations.
Each accepts a boolean or null, so REST can correctly cast their query values without a pluginPluginA 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. extending the schema:
?meta[annotations][readonly]=true
Use rest_abilities_collection_params filter when making additional metadata fields queryable, especially boolean, integer, number, array, or object values that cannot be matched correctly as untyped query strings.
Backward compatibility
The $args parameter is optional:
$abilities = wp_get_abilities();
Existing calls remain valid, and the function still returns an array of WP_Ability instances keyed by ability name.
Code that manually filters the result can continue to work:
However, plugins should migrate common category, namespace, and metadata checks to the new arguments. Doing so reduces duplicated code and allows Core and other integrations to use consistent matching behaviour.
One behavioural detail deserves particular attention: the two new global filters run even when wp_get_abilities() is called without arguments.
As a result, the following call now means “retrieve abilities through the standard filtering pipeline”:
$abilities = wp_get_abilities();
It does not necessarily mean “retrieve raw registry contents,” because another plugin can alter the result through wp_get_abilities_item_include and wp_get_abilities_result.
Retrieving the raw registry
Code that specifically needs the complete, unfiltered registry can use WP_Abilities_Registry::get_all_registered():
Most application and integration code should continue using wp_get_abilities(). Direct registry access is appropriate only when raw registered state is explicitly required, such as low-level debugging or registry inspection.
Filtering does not replace authorisation
Filtering controls which abilities are returned during discovery. It does not determine whether the current user may execute an ability.
An ability’s permission_callback remains responsible for authorisation:
Developers should not assume that an ability returned by wp_get_abilities() is executable by the current user.
Similarly, excluding an ability from a filtered result is not a security boundary. Any sensitive operation must enforce its permissions when the ability is executed.
Use wp_get_abilities_item_include or wp_get_abilities_result only for behaviour intended to affect ability retrieval across callers.
Use WP_Abilities_Registry::get_all_registered() only when code explicitly requires raw, unfiltered registry data.
Together, these changes make wp_get_abilities() the shared discovery and filtering primitive for the Abilities APIAPIAn 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., replacing duplicated filtering implementations with a consistent, extensibleExtensibleThis is the ability to add additional functionality to the code. Plugins extend the WordPress core software. pipeline.
These changes were introduced in changeset [62420] for TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.ticketticketCreated for both bug reports and feature development on the bug tracker.#64990.
Props to @benjamin_zekavica for peer review, and @gziolo for review, technical guidance, and suggested improvements.
WordPress 7.1 introduces a new public metadata flag for abilities. The flag provides a single, high-level way to indicate that an ability is intended to be available to external clients such as the REST APIREST APIThe 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/, MCP adapters, and AI agents.
Table of contents:
Previously, ability authors had to express that intent separately for every exposure channel. For example, an ability exposed through the REST API needed to set show_in_rest directly:
'meta' => array(
'show_in_rest' => true,
),
As the Abilities APIAPIAn 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. gains more client integrations, repeating the same intent through several channel-specific flags becomes difficult to maintain. The new public flag establishes a common default while preserving granular control for each channel.
Registering a public ability
An ability intended for client exposure can now set meta.public when it is registered:
For the REST API, setting public to true makes show_in_rest default to true. The ability can therefore be discovered and invoked through the REST abilities endpoints, subject to its permission callback.
How exposure defaults are resolved
Channel-specific settings take precedence over the general public setting. The effective REST exposure value is resolved as follows:
The resolution uses null-coalescing semantics so an explicit false is preserved. It is not treated as a missing value.
A null value is treated as unset and falls back to the next value in the chain.
In practical terms:
Registration metadata
Effective public
Effective show_in_rest
No exposure metadata
false
false
public => true
true
true
public => false
false
false
show_in_rest => true
false
true
public => true, show_in_rest => false
true
false
public => false, show_in_rest => true
false
true
This precedence allows for a broad exposure default while opting in or out of individual channels.
What problem does this change fix?
Ability metadata already contained channel-specific exposure settings such as show_in_rest. As support for MCP, AI agents, and other clients develops, requiring ability authors to configure each channel independently would duplicate the same policy across multiple properties:
This also makes it difficult for a newly introduced channel to determine whether an existing ability was intended for external use.
The public flag fixes this by recording the ability author’s general exposure intent in one stable location:
'meta' => array(
'public' => true,
),
Individual integrations can use that value as their default while retaining a more specific channel-level override.
REST is the first built-in consumer of this behaviour. Other integrations can adopt the same default without adding channel-specific logic to WordPress CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress..
Using public in other integrations
The resolved public value remains available in the ability’s metadata. Client integrations can inspect this value when determining whether an ability should be exposed.
The WordPress MCP Adapter will respect the unified public flag starting with its next release. WP-CLIWP-CLIWP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/https://make.wordpress.org/cli/ does not apply this exposure check because its ability-listing functionality returns all registered abilities.
Other integrations should generally resolve exposure when abilities are selected for that integration:
Integrations that need to derive their own channel-specific metadata during registration can use the existing wp_register_ability_argsfilterFilterFilters 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.:
An integration should follow the same precedence rule as REST:
Use an explicit channel-specific value when present.
Otherwise, inherit public.
Otherwise, use the channel’s built-in default.
Integrations should not overwrite an explicit channel opt-out merely because public is true.
Exposure is not authorisation
The public flag controls discoverability and client exposure. It does not make an ability executable without authorisation, and it does not replace the ability’s permission_callback.
Every ability must continue to implement an appropriate permission check:
An ability with public => true may be visible through a client while still requiring authentication and specific WordPress capabilitiescapabilityA capability is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability). to execute.
Developers should not treat public, show_in_rest, or any other exposure flag as a security boundary. Authorisation must be enforced by the ability itself.
Changes to resolved metadata
In WordPress 7.1, the resolved metadata for every ability includes a boolean public property. It defaults to false when it is not supplied during registration.
For example:
$ability = wp_get_ability( 'my-plugin/export-users' );
$meta = $ability->get_meta();
$is_public = $meta['public']; // Always a boolean in WordPress 7.1.
This gives consumers a consistent value to inspect without having to test whether the key exists.
The new property is also declared in the REST API’s ability metadata schema, allowing REST clients to inspect the general exposure intent.
Backward compatibility
The change does not alter the signature or return value of wp_register_ability() or other Abilities API functions.
Existing channel-specific registrations continue to work:
'meta' => array(
'show_in_rest' => true,
),
An explicit show_in_rest value remains authoritative. Plugins are not required to replace it with public.
Abilities that previously supplied neither public nor show_in_rest remain unavailable through REST. Their resolved metadata now contains public => false, but their exposure behaviour is unchanged.
Developers should consider migrating from show_in_rest => true to public => true when an ability is generally intended for use by multiple client types. Continue using show_in_rest directly when exposure is intentionally limited to REST or when overriding the general policy.
Existing Core abilities
The following abilities included with WordPress now use meta.public instead of setting meta.show_in_rest directly:
core/get-site-info
core/get-user-info
core/get-environment-info
Their REST availability has not changed. Because public => true supplies the default for show_in_rest, these abilities remain exposed through REST as before.
Using the high-level flag also allows other client integrations to recognise that these Core abilities are intended for external use.
When to use each flag
Use public when the ability is generally intended for consumption by external clients.
Use a channel-specific flag when:
The ability should be exposed through only that channel.
The ability needs to opt out of a channel despite being generally public.
A client integration provides behaviour that cannot be represented by the general flag.
The change was introduced in changeset [62729], with Core abilities migrated in changeset [62737]. See TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.ticketticketCreated for both bug reports and feature development on the bug tracker.#65568 for the complete discussion.
WordPress 7.1 introduces a shared JSONJSONJSON, 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 preparation layer for schemas exposed to REST clients, frontend applications, and AI tools.
WordPress accepts several internal schema conventions that are useful during server-side validation but are not portable JSON Schema draft-04. Passing these schemas directly to external validators could cause validation errors or expose PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher callbacks and other server-only implementation details.
The wp_prepare_json_schema_for_client() function
The new wp_prepare_json_schema_for_client() function converts a WordPress schema into a portable, client-facing representation before it is exposed to REST clients, frontend applications, AI tools, or other external consumers.
Most developers do not need to take action. CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. now applies this preparation automatically to:
Abilities APIAPIAn 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. schemas exposed through REST responses.
Ability input schemas converted into AI Client function declarations.
This keeps the schemas used by clients (REST clients, JavaScriptJavaScriptJavaScript 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 applications, and AI tools) consistent. See ticketticketCreated for both bug reports and feature development on the bug tracker.#64955 and changeset [62591].
Compatibility guidance
This change is primarily automatic. Existing ability registration and execution code does not need to call the new function.
Call wp_prepare_json_schema_for_client() directly when a pluginPluginA 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. exposes a WordPress-style schema outside the server-side PHP validation boundary, for example through:
a custom REST endpoint;
a JavaScript configuration object;
an MCP tool declaration;
an AI function declaration; or
another external schema consumer.
Do not replace the schema stored by an ability with the prepared version. Keep the canonical WordPress schema for server-side use and prepare a copy only when sending it to a client.
Choosing a schema profile
This new function accepts a schema and an optional schema profile:
/**
* Prepares a JSON Schema for clients.
*
* @param array<string, mixed> $schema The schema array.
* @param string $schema_profile Optional. Name of the schema
* profile whose keywords should be
* preserved. Default 'draft-04'.
* @return array<string, mixed> The prepared schema.
*/
wp_prepare_json_schema_for_client(
array $schema,
string $schema_profile = 'draft-04'
): array
WordPress provides two schema profiles out of the box:
draft-04is the default. Use it when publishing a standalone schema to general-purpose clients, including Ability metadata, frontend validators, MCP integrations, and AI tooling. It preserves the broader JSON Schema Draft 4 vocabulary, including composition and reference keywords such as $ref, definitions, allOf, not, dependencies, and additionalItems.
rest-api uses the narrower keyword set supported by WordPress REST APIREST APIThe 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/ route schemas. Use it when preparing a schema that must follow the same conventions as a REST route’s argument or response schema.
// General client-facing or Ability schema.
$prepared_schema = wp_prepare_json_schema_for_client( $schema );
// Schema intended to match WordPress REST API conventions.
$prepared_rest_schema = wp_prepare_json_schema_for_client(
$schema,
'rest-api'
);
Both profiles produce JSON Schema Draft 4 output. The difference is the set of keywords retained in the prepared schema.
What is JSON Schema Draft 4?
“Draft 4” refers to the fourth published draft of the JSON Schema specification, which defines a JSON-based contract for describing and validating JSON data. See the JSON Schema Draft 4 core specification for its terminology and behaviour.
Schema transformations
Preparation is recursive and applies to nested object properties, array items, composition keywords, definitions, dependencies, and other subschemas.
Required properties use Draft 4 syntax
WordPress schemas may mark individual properties as required:
The prepared schema moves those property names into the containing object’s Draft 4 required array:
'required' => array( 'title' ),
The property-level boolean is then removed.
If the object already has a valid required array, that array takes precedence over property-level boolean values. A property-level required => false is removed without creating an empty required array.
A boolean required value on a scalar schema is also removed because it has no Draft 4 equivalent.
This preparation only affects schemas sent to clients. It does not change the server-side behaviour of rest_validate_value_from_schema() or WP_Ability::validate_input().
PHP callbacks and other WordPress-specific keywords cannot be represented meaningfully in JSON. The preparation process removes unsupported keywords, including:
sanitize_callback
validate_callback
arg_options
These keywords are removed recursively, including when they appear inside:
properties
patternProperties
definitions
dependencies
items
additionalItems
additionalProperties
anyOf
oneOf
allOf
not
The callbacks remain available in the original server-side schema. They are removed only from its client-facing representation.
Ability authors should also note that validate_callback and sanitize_callback are not executed by the Abilities API’s runtime validation. Custom ability validation should use the wp_ability_validate_input and wp_ability_validate_outputfilters introduced in WordPress 7.1.
Empty object defaults are represented as objects
In PHP, an empty array serializes to [], even when its schema declares an object:
For client-facing schemas, the empty default is prepared so that JSON serialization produces an object:
{
"type": "object",
"default": {}
}
This prevents client validators from rejecting the default because its serialized type does not match the declared object type.
Allowed keywords filterFilterFilters 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.
wp_prepare_json_schema_for_client() uses wp_get_json_schema_allowed_keywords() to decide which keywords to preserve.
The broader draft-04 profile can preserve composition and documentation keywords such as:
$ref
definitions
allOf
not
dependencies
additionalItems
Preserving a keyword means that it may be included in the client-facing schema. It does not mean that WordPress validates or sanitizes values against that keyword on the server.
This prevents WordPress-only schema keywords and nonportable required conventions from being passed directly into AI function declarations.
The helper prepares a portable Draft 4 schema; it is not a provider-specific compiler. Individual AI providers may support a smaller schema vocabulary or impose additional requirements. Provider-specific adaptation may therefore still occur elsewhere in the integration.
Follow-up
Provider-specific adaptation is tracked in WordPress/php-ai-client#256: each provider should be able to override the input schema for its own API requirements, which differ across providers and evolve over time.
Related ticket
#64955 — Add schema compiler for AI tool calling compatibility
WordPress 7.1 expands the Abilities APIAPIAn 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. with custom validation hooksHooksIn 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., a new invocation lifecycle action, richer user information, selective field responses, and more consistent schemas for the coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. abilities introduced in WordPress 6.9.
Custom input and output validation
WP_Ability validates input and output against each ability’s JSONJSONJSON, 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. WordPress 7.1 adds two filters that let extenders supplement that validation:
wp_ability_validate_input
wp_ability_validate_output
Each filterFilterFilters 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. receives the existing validation result, the value being validated, and the ability name:
For example, a pluginPluginA 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. can enforce a rule that cannot be expressed by the JSON Schema implementation used by WordPress:
add_filter(
'wp_ability_validate_input',
function ( $is_valid, $input, $ability_name ) {
if ( 'my-plugin/send-message' !== $ability_name ) {
return $is_valid;
}
// Preserve errors produced by the default schema validation.
if ( is_wp_error( $is_valid ) ) {
return $is_valid;
}
if (
! is_array( $input )
|| empty( $input['recipient'] )
|| ! str_ends_with( $input['recipient'], '@example.com' )
) {
return new WP_Error(
'invalid_recipient',
__( 'The recipient must use the example.com domain.', 'my-plugin' )
);
}
return true;
},
10,
3
);
Output can be validated in the same way:
add_filter(
'wp_ability_validate_output',
function ( $is_valid, $output, $ability_name ) {
if ( 'my-plugin/send-message' !== $ability_name ) {
return $is_valid;
}
if ( is_wp_error( $is_valid ) ) {
return $is_valid;
}
if ( ! is_array( $output ) || empty( $output['message_id'] ) ) {
return new WP_Error(
'invalid_message_output',
__( 'The ability did not return a message ID.', 'my-plugin' )
);
}
return true;
},
10,
3
);
Callbacks should return true when the value is valid or a WP_Error describing why it is invalidinvalidA 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.. Returning false also fails validation, but WordPress converts it to a generic WP_Error. The filters operate on the validation result rather than the schema, allowing plugins to augment an existing error or reject data that otherwise passed JSON Schema validation.
REST-style validate_callback and sanitize_callback schema keywords are not executed by the Abilities API. Custom runtime validation should use these new filters. See ticketticketCreated for both bug reports and feature development on the bug tracker.#64311.
Observing every ability invocation
WordPress 7.1 adds the wp_ability_invoked action at the beginning of WP_Ability::execute():
The action fires before input normalization, validation, permission checks, and the wp_pre_execute_ability short-circuit filter. Consequently, it runs for every invocation, including calls that:
contain invalid input;
fail their permission check;
are short-circuited;
return a cached result;
require approval; or
proceed to the execution callback.
This makes the action suitable for auditing, telemetry, tracing, and invocation accounting:
The action receives raw, unnormalized input. Plugins should therefore avoid logging input indiscriminately, because it may contain credentials, personal information, or other sensitive data.
The existing wp_before_execute_ability and wp_after_execute_ability actions also receive the corresponding WP_Ability instance as an additional final argument. Existing callbacks continue to work unchanged. To receive the new argument, update the callback signature and $accepted_args. See ticket #65248.
Expanded core/get-user-info responses
The core/get-user-info ability now returns five additional profile fields for the current authenticated user:
first_name
last_name
nickname
description
user_url
When no input is supplied, the response contains all supported properties:
The roles property is now normalized with array_values() so that it is consistently encoded as a JSON array, regardless of its PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higher array keys.
Callers can also use the new optional fields input property to request a subset of the response:
Supported field names are declared through an enum in the input schema. Passing an unknown name causes execution to return an ability_invalid_input error before the ability callback runs.
The permission requirement remains unchanged: the requester must be logged in. See ticket #65234 and changeset [62419].
Consistent schemas across core abilities
The following core abilities now follow the same schema conventions:
core/get-site-info
core/get-user-info
core/get-environment-info
Every output property declares a translatable, Title Case title and a description. This provides better metadata to REST, MCP, WebMCP, AI, and other programmatic clients that use the schema to present or select ability fields.
core/get-environment-info now supports the same optional fields input as the other two abilities:
Unknown field names are rejected through schema validation.
In addition, core/get-user-info is now exposed through the REST APIREST APIThe 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/. Like the other core abilities, it declares the new publicmetaMetaMeta 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. flag introduced in WordPress 7.1. Authenticated clients can discover it through:
/wp-json/wp-abilities/v1/abilities
The exact ordered set of input field names and output properties is covered by registration tests. Developers extending or consuming these core abilities should use the schemas for discovery rather than assuming a fixed response shape. See ticket #65355.
Typed input for REST ability runs
REST requests that run an ability over GET or DELETE deliver every query string value as a string, and a comma-separated list as a single string. In previous releases, the ability received this input as-is: an integer arrived as "10", a boolean as "true", and strict comparisons inside the callback silently failed unless the ability hand-rolled its own casting.
WordPress 7.1 coerces the input of a run request to the types declared in the ability’s input_schema before the ability runs. The coercion is registered as the input argument’s sanitize_callback, so the permission callback and the execute callback both receive natively typed input from the same request object:
GET /wp-json/wp-abilities/v1/abilities/my-plugin/list-items/run
?input[limit]=10&input[featured]=true&input[ids]=1,2,3
With an input schema declaring limit as an integer, featured as a boolean, and ids as an array of integers, the callbacks now receive:
Coercion never changes what validation accepts. Input is coerced only when validate_input() already accepts it, so invalid input reaches validation untouched and returns the same ability_invalid_input error as before.
WordPress 6.1 includes an enhancementenhancementEnhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. to the search controller, #56546, which makes it possible to retrieve a term or post object over the REST APIREST APIThe 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/ without knowing anything but that resource’s ID and object type.
get_post can retrieve a post of any post type so long as you know the post’s numeric ID, and get_term can retrieve a term from any taxonomyTaxonomyA 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.. Because REST objects are segregated by post type-specific endpoints, however, there has not been a clear way to get a Post with ID 78 if you don’t know whether it is a page, post, or my-cpt.
The coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress./search endpoint now supports ?include and ?exclude parameters which take a list of IDs, and limit results to posts matching those IDs.
Examples:
To get post 78 when you don’t know its post type,
/wp/v2/search?include=78
To get posts 78 and 79 only if they are in the page post type,
/wp/v2/search?include=78,79&subtype=page
To search posts excluding post 78,
/wp/v2/search?exclude=78
To get term 87,
/wp/v2/search?type=term&include=78
To get term 87 only if it is a categoryCategoryThe 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging.,
The search endpoint supports the _embedmetaMetaMeta 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. parameter, so developers can therefore use the search endpoint to retrieve a full post or term response object in one request knowing only those object’s IDs.
As an example of how this could be used, imagine a custom blockBlockBlock 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. which relates to a specific post. As of WordPress 6.1 developers can implement that block knowing only the related post’s ID, and could then create a hook to search for that post by ID and retrieve it using the Block Editor’s existing entity system:
/**
* Dictionary of requested items: keep an in-memory list of the type (if known)
* for each requested ID, to limit unnecessary API requests.
*/
const typeById = {};
​
/**
* Query for a post entity resource without knowing its post type.
*
* @param {number} id Numeric ID of a post resource of unknown subtype.
* @returns {object|undefined} The requested post object, if found and loaded.
*/
function usePostById( id ) {
const type = typeById[ id ];
​
useEffect( function() {
if ( ! id || typeById[ id ] ) {
return;
}
​
apiFetch( {
path: `/wp/v2/search?type=post&include=${ id }&_fields=id,subtype`,
} ).then( ( result ) => {
if ( result.length ) {
typeById[ id ] = result[0].subtype;
}
} );
}, [ id ] );
​
return useSelect( function( select ) {
if ( ! id || ! type ) {
return undefined;
}
return select( 'core' ).getEntityRecord( 'postType', type, id );
}, [ id, type ] );
}
Pretty-printing REST endpoint JSONJSONJSON, 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. responses
WordPress 6.1 also introduces support for returning pre-formatted JSON from the REST API. #41998 lets developers request formatted JSON using a new _pretty query parameter or a filterFilterFilters 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., particularly useful when querying via curl or other tools which do not provide an option to format responses.
To format the JSON returned from a specific endpoint request, append the ?_pretty query parameter to the endpoint URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org.
To instruct WordPress to pretty-print all REST response bodies, a developer can use the rest_json_encode_options filter:
WordPress 6.1 brings a number of key improvements to the REST APIREST APIThe 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/ to increase performance. These improvements decrease the number of database queries that are run on each REST API request.Â
Avoid unnecessarily preparing item links
Prior to WordPress 6.1, the prepare_links method in the REST API was called in all controllers. If the _fields parameter is passed to the REST API request, it might mean that the links field is not requested and would never be returned in the response. This is wasteful, as prepare_links can contain database calls or other complex logic that would be run even if it never returned the response.Â
In 6.1 prepare_links are only called if requested in the response, when links are requested in fields or the _embedded parameter is passed. As part of this work, the taxonomyTaxonomyA 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. and post type controllers have now been updated to implement said prepare_links method to bring them in line with other REST API controllers.Â
This is the code example of implementing this change in custom REST API controllers.
This logic conditionally calls prepare_links only if _links or _embedded is requested. This logic only applies when using the _fields query parameter. When not using _fields, links are included in the response as normal.Â
For more info see TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.ticketticketCreated for both bug reports and feature development on the bug tracker.: #52992, #56019, #56020
Improvement to the Posts controller
When running profiling tools against the responses of REST API requests, it was discovered that post controllers request a lot of linked data to each post. For example, when returning a post in a REST API response, linked data such as author (user), featured imageFeatured imageA featured image is the main image used on your blog archive page and is pulled when the post or page is shared on social media. The image can be used to display in widget areas on your site or in a summary list of posts., and parent post were all requested. As these linked items were not primed in caches, it could mean that for each post in the REST API response there would be 3 separate database queries: one for the user, one for the featured image, and another for the parent post.Â
In WordPress 6.1 all the caches are primed in a single database query and there are new helper functions to enable this:
update_post_author_caches
Takes an array of posts and primes users caches in a single query.Â
update_post_parent_caches
Takes an array of posts and primes post parents in a single query.Â
update_menu_item_cache
Takes an array of posts and primes post / terms link to menu items single query.Â
The existing function update_post_thumbnail_cache was used to prime featured image caches. These functions are also being rolled out to other parts of the coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. that can benefit from priming caches in a single place.Â
The comments and user controllers have also been improved: User controller now primes user metaMetaMeta 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. in a single query and the comments controller now primes the linked post cache in a single query. Improvements were made to the post search controller to improve database performance along with the media controller.Â
WordPress 5.9 adds three new REST APIREST APIThe 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 to manage menus and menu locations. These menus endpoints are used the in new navigation block.
Before discussing menu endpoints, it’s worth noting how menus are currently stored. Navigation menus are stored using the nav_menutaxonomyTaxonomyA 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. and the nav_menu_item post type. A menu is stored as a term and acts like a container for a number of menu items. Menu items are stored as posts. Menus and menu items also have custom fields stored in metaMetaMeta 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. and in various options.
Menus
Accessible via /wp/v2/menus, the menus endpoint allows for performing CRUDCRUDCreate, read, update and delete, the four basic functions of storing data. (More on Wikipedia.) operations on menu data. This endpoint extends the WP_REST_Terms_Controller class, mapping fields to the menus and adding functionality like auto_add, that automatically adds new pages to menus when created. A GET request includes the list of menus, but does not contain the list of menu items. To get this data, the menu items endpoint can be used.
Accessible via /wp/v2/menu-items, the menu items endpoint allows for performing CRUD operations on menu items and assigning them to menus. This endpoint extends the WP_REST_Posts_Controller class, mapping fields and adding custom functionality. Menu items can only be assigned to one menu at a time unlike other taxonomies.
Many menu items have an associated object that the menu item links to. For instance, a link to a page will have the object set to page and the object_id set to the WordPress Post ID of that page. When using this endpoint, it may be useful to get information about that linked object. For example the page’s title. This information is not included in the response by default, but the REST API has a feature to embed this information by using the _embed query parameter. For example, making a GET request to /wp/v2/menu-item/8874?_embed=true will result in the following response:
Accessible via /wp/v2/menu-locations, the menu locations endpoint returns a list of menu locations registered with the register_nav_menus function. To assign a menu to a particular location, use the menus endpoint, by passing an array of menu location keys.
Both the menu and menu item endpoints, both support the batching of requests, introduced in WordPress 5.6. This means that more than one menu / menu item can be updates / created in a simple request to the APIAPIAn 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..
Access Control
To access data from any of the menus endpoints, requests must be made by a logged in user with the edit_theme_options capabilitycapabilityA capability is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability).. By default, only users with the Administrator role have this capability. This means that menu data is not publically exposed via the REST API. TicketticketCreated for both bug reports and feature development on the bug tracker.#54304 provides a means for developers to opt-in to exposing this data publicly. The REST API team hopes to implement this feature in a near future release of WordPress.
These endpoints were first developed as a feature pluginFeature PluginA plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins on GitHub. For those using this pluginPluginA 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., after upgrading to WordPress 5.9, the plugin can be deactivated and removed as all of it’s functionality is now included in WordPress CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress..
The following is a snapshot of some of the changes to the REST APIREST APIThe 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/ in WordPress 5.8. For more details, see the full list of closed tickets.
Widgets
WordPress 5.8 sees the introduction of a new blockBlockBlock 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.-based widgets editor and with it the creation of several REST API endpoints dedicated to widgetWidgetA WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user. management. Before diving in to how the new endpoints operate, I’d like to provide some background about how widgets work that should make the following sections more clear.
Instance Widgets
The predominant way to create widgets is to subclass the WP_Widget base class and register the widget with register_widget. These are referred to as “multi” widgets. These widgets have multiple instances that are identified by their number, an incrementing integer for each widget type.
Each instance has its own setting values. These are stored and fetched by WP_Widget which allows for the REST API to include these values. However, since a widget’s instance can contain arbitrary data, for example a DateTime object, the REST API cannot always serialize a widget to JSONJSONJSON, 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.. As such, a widget’s data is always serialized using the PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 7.4 or higherserialize function and then base64 encoded. This data is also exposed with a hash value which is a wp_hash signature of this value to prevent clients from sending arbitrary data to be deserialized with unserialize.
For widgets that can be safely accept and expose their instance data as JSON, pass the show_instance_in_rest flag in the $widget_options parameter.
class ExampleWidget extends WP_Widget {
...
/**
* Sets up the widget
*/
public function __construct() {
$widget_ops = array(
// ...other options here
'show_instance_in_rest' => true,
// ...other options here
);
parent::__construct( 'example_widget', 'ExampleWidget', $widget_ops );
}
...
}
Reference Widgets
Far less common, but still supported, are widgets that are registered using wp_register_sidebar_widget and wp_register_widget_control directly. These are referred to as “reference”, “function-based”, or “non-multi” widgets. These widgets can store their data in an arbitrary location. As such, their instance values are never included in the REST API.
Widget Types
Accessible via /wp/v2/widget-types, the widget types endpoint describes the different widget types that are registered on the server. The endpoint is accessible to users who have permission to edit_theme_options. By default, this is limited to Administrator users.
Response Format
{
"id": "pages",
"name": "Pages",
"description": "A list of your site’s Pages.",
"is_multi": true,
"classname": "widget_pages",
"_links": {
"collection": [
{
"href": "https://trunk.test/wp-json/wp/v2/widget-types"
}
],
"self": [
{
"href": "https://trunk.test/wp-json/wp/v2/widget-types/pages"
}
]
}
}
Encode Endpoint
Multi widgets have access to the /wp/v2/widget-types/<widget>/encode endpoint. This endpoint is used to convert htmlHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. form data for the widget to the next instance for the widget, render the widget form, and render the widget preview.
For example, let’s say we want to interact with the MetaMetaMeta 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. widget. First, we’ll want to request the widget form from the server.
POST /wp/v2/widget-types/meta/encode
{
"instance": {},
"number": 1
}
For now, let’s assume we’re working with a new widget. The instance is empty because this is a new widget, so we’ll be rendering an empty form. The number argument can be omitted, but including one is recommended to provide stable input ids. You’ll receive a response similar to this. The widget preview has been snipped for brevity.
The provided form can then be rendered and edited by the user. When you want to render a new preview or are ready to begin saving, call the encode endpoint again with the url encoded form data and the instance value returned from the first response.
The REST API will call the widget’s update function to calculate the new instance based on the provided form data. The instance object can then be used to save a widget via the widgets endpoint.
The widgets endpoint is used for performing CRUDCRUDCreate, read, update and delete, the four basic functions of storing data. (More on Wikipedia.) operations on the saved widgets. Like the widget types endpoint, the widgets endpoints required the edit_theme_optionscapabilitycapabilityA capability is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability). to access.
To retrieve widgets, make a GET request to the /wp/v2/widgets endpoint. The sidebar parameter can be used to limit the response to widgets belonging to the requested sidebarSidebarA sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme..
To create a widget, for instance the widget from our previous example, make a POST request to the /wp/v2/widgets endpoint. The instance is the same value returned from the encode endpoint. The id_base is the unique identifier for the widget type and sidebar is the id of the sidebar to assign the widget to. Both are required.
Since the meta widget (and all other built-in widgets) is registered with show_instance_in_rest enabled you could bypass the encode endpoint and use instance.raw instead. For example, if we wanted to update the widget to have a new title, we could make the following PUT request to /wp/v2/widgets/meta-1.
A PUT request can also be made to update the sidebar assigned to a widget by passing a new sidebar id in the request.
To delete a widget, send a DELETE request to the individual widget route. By default, deleting a widget will move a widget to the Inactive Widgets area. To permanently delete a widget, use the force parameter. For example: DELETE /wp/v2/widgets/meta-1?force=true.
Sidebars Endpoints
Found under /wp/v2/sidebars, the sidebars endpoint is used to manage a site’s registered sidebars (widget areas) and their assigned widgets. For example, the following is the response for the first footer area in the Twenty Twenty theme.
{
"id": "sidebar-1",
"name": "Footer #1",
"description": "Widgets in this area will be displayed in the first column in the footer.",
"class": "",
"before_widget": "<div class=\"widget %2$s\"><div class=\"widget-content\">",
"after_widget": "</div></div>",
"before_title": "<h2 class=\"widget-title subheading heading-size-3\">",
"after_title": "</h2>",
"status": "active",
"widgets": [
"recent-posts-2",
"recent-comments-2",
"meta-1"
],
"_links": {
"collection": [
{
"href": "https://trunk.test/wp-json/wp/v2/sidebars"
}
],
"self": [
{
"href": "https://trunk.test/wp-json/wp/v2/sidebars/sidebar-1"
}
],
"wp:widget": [
{
"embeddable": true,
"href": "https://trunk.test/wp-json/wp/v2/widgets?sidebar=sidebar-1"
}
],
"curies": [
{
"name": "wp",
"href": "https://api.w.org/{rel}",
"templated": true
}
]
}
}
The widgets property contains an ordered list of widget ids. While all other properties are readonly, the widgets property can be used to reorder a sidebar’s assigned widgets. Any widget ids omitted when updating the sidebar will be assigned to the Inactive Widgets sidebar area.
For example, making a PUT request to /wp/v2/sidebars/sidebar-1 with the following body will remove the Recent Comments widget, and move the Meta widget to the top of the sidebar.
PUT /wp/v2/sidebars/sidebar-1
{
"widgets": [
"meta-1",
"recent-posts-2"
]
}
For more information about the changes to widgets in 5.8, check out the Block-based Widgets Editor dev notedev noteEach 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..
By default, a post must contain at least one of the requested terms to be included in the response. As of [51026], the REST API accepts a new operator property that can be set to AND to require a post to contain all of the requested terms.
For example, /wp/v2/posts?tags[terms]=1,2,3&tags[operator]=AND will return posts that have tags with the ids of 1, 2, and 3.
The following is a snapshot of some of the changes to the REST APIREST APIThe 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/ in WordPress 5.7. For more details, see the full list of closed tickets.
Introduced in 50157, the REST API posts collection endpoints have been updated to allow a more complex syntax for specifying the tax_query used when querying posts. Each taxonomyTaxonomyA 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.’s query parameters can now both accept a list of term ids or an object with a terms property.Â
Hierarchical taxonomies support an include_children property alongside terms. By default it’s disabled, but if set to true the flag is enabled for the generated tax_query to enable searching for posts that have the given terms or terms that are children of the given terms.
Introduced in 50024 the REST API posts collection endpoints now accept modified_before and modified_after query parameters to query posts based on the post modified date instead of the post published date.
As a result of this change, the posts controller now uses a date_query with a separate clause for each date related query parameter instead of a single clause with the before and after flags set.
Multiple MetaMetaMeta 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. Values for a Key Can Be Deleted by Sending an Empty Array
Previously, to remove all values for a specific meta key, passing null as the value for that meta key was required. After 49966 an empty array can be passed instead.
As of 49925, the themes endpoint now returns all themes installed on the site, not just the active theme. By default, the endpoint returns both active and inactive themes, but the status query parameter can be used to limit the list to themes with the desired status.
Note, the theme_supports value is only exposed for the active theme. The field is omitted for inactive themes since declaring the supported theme features requires calls to add_theme_support which can only be done if the theme is active.
When querying solely for active themes, the only permission required is to be able to edit posts of any show_in_rest post type. However when querying for inactive themes the switch_themes or manage_network_themes capabilitycapabilityA capability is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability). is required.
In addition to the changes to the collection endpoint, a new single theme endpoint is available. For example, /wp/v2/themes/twentytwentyone will return information about Twenty Twenty One. For convenience, a link is also added to the currently active theme in the REST API Index if the current user has the requisite permissions. This is the recommended way for applications to discover the currently active theme.
The /wp/v2/media/<id>/edit endpoint introduced in WordPress 5.5 came with a limited APIAPIAn 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. that accepted top-level rotation and crop declarations. In 50124 this API was made more powerful and flexible by accepting an array of modifications in the new modifiers request parameter.
The previous query parameters have been marked as deprecated, but will continue to function as normal and do not currently issue deprecation warnings. Clients are encouraged to switch to the new syntax.
To alleviate server resources, whenever possible, clients should simplify redundant modifications before sending the request.
In 50010 support for type coercion was added to the enum JSONJSONJSON, 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 keyword. Previously, the enum keyword was validated by perform a strict equality check. For string types this is generally ok, but it prevented using alternative types like number when rich type support isn’t available.
Now the same level of type coercion/sanitization is applied when validating enum as all other validation checks. This means that a value of "1" will be accepted for an enum of [ 0, 1 ]. Additionally, object types now properly ignore key order when checking for equality.
As of 50007, the rest_validate_value_from_schema function now returns specific error codes for each validation failure instead of the generic rest_invalid_param. For instance, if more array items are given than allowed by maxItems, the rest_too_many_itemserror code will be returned.
Return Detailed Error Information from Request Validation
Previously when a parameter failed validation only the first error message specified in the WP_Error instance was returned to the user. Since 50150 the REST API will now return detailed error information as part of the details error data key.
{
"code": "rest_invalid_param",
"message": "Invalid parameter(s): enum_a, enum_b",
"data": {
"status": 400,
"params": {
"enum_a": "enum_a is not one of a, b, c.",
"enum_b": "enum_b is not one of d, e, f."
},
"details": {
"enum_a": {
"code": "rest_not_in_enum",
"message": "enum_a is not one of a, b, c.",
"data": {
"enum": ["a", "b", "c"]
}
},
"enum_b": {
"code": "rest_not_in_enum",
"message": "enum_b is not one of d, e, f.",
"data": {
"enum": ["d", "e", "f"]
}
}
}
}
}
Fine Grained CapabilitiescapabilityA capability is permission to perform one or more types of task. Checking if a user has a capability is performed by the current_user_can function. Each user of a WordPress site might have some permissions but not others, depending on their role. For example, users who have the Author role usually have permission to edit their own posts (the “edit_posts” capability), but not permission to edit other users’ posts (the “edit_others_posts” capability).
When the Application Passwords REST API controllers were introduced, the edit_user meta capability was used for all permission checks. As of 50114, the REST API now uses specific meta capabilities for each action type.
create_app_password
list_app_passwords
read_app_password
edit_app_password
delete_app_password
delete_app_passwords
By default, these capabilities all map to edit_user however they can now be customized by using the map_meta_cap filterFilterFilters 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..
50065 introduces a new Application Passwords endpoint for introspecting the app password being currently used for authentication. This endpoint is accessible via /wp/v2/users/me/application-passwords/introspect and will return the same information as the other endpoints. This allows for an application to disambiguate between multiple installations of their application which would all share the same app_id.
Clients can use this information to provide UIUIUser interface hints about how the user is authenticated, for instance by displaying the App Passwords’s label. Or when their application is uninstalled by the user, they can automatically clean up after themselves by deleting their App Password.
As of 50030 the Application Passwords API enforces that each App Password has a unique name that cannot consist solely of whitespace characters. Additionally, invalidinvalidA 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. characters are stripped from the provided application name.
WordPress 5.6 introduces a number of changes to the REST APIREST APIThe 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/, some of which have been covered in other dev notesdev noteEach 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.
Search
The wp/v2/search endpoint introduced in WordPress 5.0 provides a unified interface for searching across multiple content types. WordPress 5.6 adds a terms and post formats search handler. For example, to search across terms in all taxonomies, make the following request: https://example.org/wp-json/wp/v2/search?type=term&search=my-term. To search post-formats, use the post-format type: https://example.org/wp-json/wp/v2/search?type=post-format&search=aside.
Additionally, the REST API search infrastructure no longer requires that the id for each item is an integer. Strings are now an acceptable id type.
JSONJSONJSON, 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
multipleOf keyword
The multipleOf keyword allows for asserting that an integer or number type is a multiple of the given number. For example, this schema will only accept even integers.
{
"type": "integer",
"multipleOf": 2
}
multipleOf also supports decimals. For example, this schema could be used to accept a percentage with a maximum of 1 decimal point.
The minItems and maxItems keywords can be used for the array type. The minProperties and maxProperties introduces this same functionality for the object type. This is helpful when using additionalProperties to have a list of objects with unique keys.
This schema requires an object that specifies at least 1, and at most 3, colors.
The patternProperties keyword is similar to the additionalProperties keyword, but allows for asserting that the property matches a regex pattern. The keyword is an object where each property is a regex pattern and its value is the JSON Schema used to validate properties that match that pattern.
For example, this schema requires that each value is a hex color and the property must only contain “word” characters.
When the REST API validates the patternProperties schema, if a property doesn’t match any of the patterns, the property will be allowed and not have any validation applied to its contents. This behaves the same as the properties keyword. If this logic isn’t desired, add additionalProperties to the schema to disallow non-matching properties. See #51024.
oneOf and anyOf
These are advanced keywords that allow for the JSON Schema validator to choose one of many schemas to use when validating a value. The anyOf keyword allows for a value to match at least one of the given schemas. Whereas, the oneOf keyword requires the value match exactly one schema.
For example, this schema allows for submitting an array of “operations” to an endpoint. Each operation can either be a “crop” or a “rotation”.
The REST API will loopLoopThe 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 specified in the oneOf array and look for a match. If exactly one schema matches, then validation will succeed. If more than one schema matches, validation will fail. If no schemas match, then the validator will try to find the closest matching schema and return an appropriate error message.
operations[0] is not a valid Rotation. Reason: operations[0][degrees] must be between 0 (inclusive) and 360 (inclusive)
When making an OPTIONS request to an endpoint, the REST API will return the args that the route accepts. Previously, only a limited subset of JSON Schema keywords were exposed. In WordPress 5.6, now the full list of JSON Schema keywords that the REST API supports will be exposed. See #51020.
More specific validation error codes
When the type of a value is incorrect, rest_validate_value_from_schema now returns rest_invalid_type instead of the generic rest_invalid_param. The validation error code is not currently exposed to REST API clients. This would only effect direct usages of the validation function.
Miscellaneous
The apiRequest library now supports using the PUT and DELETEHTTPHTTPHTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. methods with servers that didn’t support those methods. This is done by making the request a POST request and passing the original HTTP method in the X-HTTP-Method-OverrideheaderHeaderThe 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.. #43605.
The comments controller now uses the rest_get_route_for_post function introduced in WordPress 5.5 to generate the up response link. This function is filterable to allow for custom controllers to properly define their REST API route. #44152.
The REST API now supports a broader range of JSON media types. Previously, only application/json was supported which prevented using subtypes like application/activity+json. The REST API will now json_decode the body of requests using a JSON subtype Content-Type. Additionally, wp_die() now properly sends the error as JSON when a JSON subtype is specified in the Accept header. #49404.