The Abilities API provides WordPress Action and Filter Hooks that allow developers to monitor and respond to ability execution events.
Actions
wp_abilities_api_categories_init
Fires when the category registry is first initialized. This is the proper hook to use when registering categories.
do_action( 'wp_abilities_api_categories_init', $registry ); Parameters
$registry(\WP_Ability_Categories_Registry): The category registry instance.
Usage Example
add_action( 'wp_abilities_api_categories_init', 'wporg_register_categories' ); /** * Register custom ability categories. * * @param \WP_Ability_Categories_Registry $registry The category registry instance. */ function wporg_register_categories( $registry ) { wp_register_ability_category( 'ecommerce', array( 'label' => __( 'E-commerce', 'textdomain' ), 'description' => __( 'Abilities related to e-commerce functionality.', 'textdomain' ), )); wp_register_ability_category( 'analytics', array( 'label' => __( 'Analytics', 'textdomain' ), 'description' => __( 'Abilities that provide analytical data and insights.', 'textdomain' ), )); } wp_abilities_api_init
Fires when the abilities registry has been initialized. This is the proper hook to use when registering abilities.
do_action( 'wp_abilities_api_init', $registry ); Parameters
$registry(\WP_Abilities_Registry): The abilities registry instance.
Usage Example
add_action('wp_abilities_api_init', 'wporg_register_abilities'); /** * Register custom abilities. */ function wporg_register_abilities() { wp_register_ability( 'wporg/ability', array( 'label' => __( 'Title', 'textdomain' ), 'description' => __( 'Description.', 'textdomain' ), 'category' => 'analytics', 'input_schema' => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => false, ), 'output_schema' => array( 'type' => 'string', 'description' => 'The site title.', ), 'execute_callback' => 'wporg_get_site_title', 'permission_callback' => '__return_true', // Everyone can access this 'meta' => array( 'show_in_rest' => true, // Optional: expose via REST API ), ) ); } wp_before_execute_ability
Fires immediately before an ability gets executed, after permission checks have passed but before the execution callback is called.
do_action( 'wp_before_execute_ability', $ability_name, $input ); Parameters
$ability_name(string): The namespaced name of the ability being executed (e.g.,wporg/get-posts).$input(mixed): The input data passed to the ability.
Usage Example
add_action( 'wp_before_execute_ability', 'log_ability_execution', 10, 2 ); /** * Log each ability execution attempt. * @param string $ability_name The name of the ability being executed. * @param mixed $input The input data passed to the ability. */ function log_ability_execution( string $ability_name, $input ) { error_log( 'About to execute ability: ' . $ability_name ); if ( $input !== null ) { error_log( 'Input: ' . wp_json_encode( $input ) ); } } wp_after_execute_ability
Fires immediately after an ability has finished executing successfully, after output validation has passed.
do_action( 'wp_after_execute_ability', string $ability_name, $input, $result ); Parameters
$ability_name(string): The namespaced name of the ability that was executed.$input(mixed): The input data that was passed to the ability.$result(mixed): The validated result returned by the ability’s execution callback.
Usage Example
add_action( 'wp_after_execute_ability', 'log_ability_result', 10, 3 ); /** * Log the result of each ability execution. * * @param string $ability_name The name of the executed ability. * @param mixed $input The input data passed to the ability. * @param mixed $result The result returned by the ability. */ function log_ability_result( string $ability_name, $input, $result ) { error_log( 'Completed ability: ' . $ability_name ); error_log( 'Result: ' . wp_json_encode( $result ) ); } Filters
wp_register_ability_args
Allows modification of an Ability’s args before they are validated and used to instantiate the Ability.
$args = apply_filters( 'wp_register_ability_args', array $args, string $ability_name ); Parameters
$args(array<string,mixed>): The arguments used to instantiate the ability. See wp_register_ability() for the full list of args.$ability_name(string): The namespaced name of the ability being registered (e.g.,wporg/get-posts).
Usage Example
add_filter( 'wp_register_ability_args', 'my_modify_ability_args', 10, 2 ); /** * Modify ability args before validation. * * @param array<string,mixed> $args The arguments used to instantiate the ability. * @param string $ability_name The name of the ability, with its namespace. * * @return array<string,mixed> The modified ability arguments. */ function my_modify_ability_args( array $args, string $ability_name ): array { // Check if the ability name matches what you're looking for. if ( 'my-namespace/my-ability' !== $ability_name ) { return $args; } // Modify the args as needed. $args['label'] = __('My Custom Ability Label'); // You can use the old args to build new ones. $args['description'] = sprintf( /* translators: 1: Ability name 2: Previous description */ __('This is a custom description for the ability %s. Previously the description was %s', 'text-domain'), $ability_name, $args['description'] ?? 'N/A' ); // Even if they're callbacks. $args['permission_callback' ] = static function ( $input = null ) use ( $args, $ability_name ) { $previous_check = is_callable( $args['permission_callback'] ) ? $args['permission_callback']( $input ) : true; // If we already failed, no need for stricter checks. if ( ! $previous_check || is_wp_error( $previous_check ) ) { return $previous_check; } return current_user_can( 'my_custom_ability_cap', $ability_name ); } return $args; } wp_register_ability_category_args
Allows modification of a category’s arguments before validation.
$args = apply_filters( 'wp_register_ability_category_args', array $args, string $slug ); Parameters
$args(array<string,mixed>): The arguments used to instantiate the category (label, description).$slug(string): The slug of the category being registered.
Usage Example
add_filter( 'wp_register_ability_category_args', 'my_modify_category_args', 10, 2 ); /** * Modify category args before validation. * * @param array<string,mixed> $args The arguments used to instantiate the category. * @param string $slug The slug of the category being registered. * * @return array<string,mixed> The modified category arguments. */ function my_modify_category_args( array $args, string $slug ): array { if ( 'my-category' === $slug ) { $args['label'] = __( 'My Custom Label', 'textdomain' ); $args['description'] = __( 'My custom description for this category.', 'textdomain' ); } return $args; }