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.
Filtering registered abilities with wp_get_abilities() in WordPress 7.1
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.