L’API Abilities, introduite dans WordPress 6.9, établit un langage commun permettant à tous les composants de WordPress — tant le cœur du logiciel que les extensions — d’exposer leurs fonctionnalités de manière unifiée et compréhensible, tant pour les humains que pour les machines. Votre site WordPress est ainsi prêt à s’intégrer à des outils d’automatisation externes de manière standardisée et sécurisée.
Si vous vous demandez à quoi pourraient ressembler certains cas d’utilisation de l’API Abilities, imaginez un modèle d’IA qui guide un utilisateur tout au long du processus d’achat et lui permet même de finaliser son achat sans se rendre sur votre site de commerce électronique. Ou imaginez un pipeline CI/CD sur GitHub Actions qui traite du texte extrait d’un fichier audio ou vidéo et l’envoie à WordPress pour publication. Les cas d’utilisation sont infinis.
L’API Abilities modifie le rôle même de WordPress au sein de l’écosystème. Ce n’est plus seulement un blog, ni même un CMS ; aujourd’hui, WordPress agit comme un moteur d’exécution distribué pouvant être orchestré de l’extérieur, à la manière d’une sorte de système d’exploitation, entièrement prêt pour les agents autonomes.
Vous souhaitez en savoir plus ? Plongeons-nous dans le vif du sujet.
À quoi sert une « ability » ?
Une « ability » est une fonctionnalité détectable et exploitable sur un site WordPress qui permet à des entités externes (telles que des modèles d’IA) ou à des composants internes d’effectuer des opérations spécifiques.
L’API peut notamment être utilisée pour :
- Rechercher du contenu ou effectuer des opérations spécifiques sur la base de données
- La lecture des réglages de configuration du site
- Créer un article
- Convertir une structure JSON en blocs Gutenberg
Exposer une capacité revient à rendre une fonctionnalité spécifique interopérable. Avant qu’une capacité puisse être découverte et utilisée, elle doit être enregistrée dans un catalogue centralisé. Ce n’est qu’alors que WordPress et les modèles d’IA pourront la découvrir, en comprendre l’intention et l’invoquer en cas de besoin.
Par défaut, les fonctionnalités de vos extensions sont totalement isolées. En enregistrant une capacité, vous déclarez que la logique sous-jacente est disponible en tant que service pour l’ensemble de l’écosystème.
Prenons un exemple. Si votre extension dispose d’une fonction qui convertit un objet JSON initial en contenu structuré prêt à être utilisé dans des blocs Gutenberg, vous pouvez l’enregistrer en tant que capacité. Cela permet à d’autres outils disposant des autorisations requises de déclencher exactement la même fonction.
Dans notre précédent tutoriel sur le WordPress AI Client, l’extension gérait la logique principale consistant à envoyer un fichier audio au modèle d’IA, qui renvoyait une réponse structurée au format JSON permettant de générer des blocs Gutenberg. Cependant, cette fonctionnalité restait limitée à notre extension. En enregistrant ce processus en tant que « capacité », vous découpliez son exécution, et n’importe quelle entité externe peut déclencher l’intégralité de la logique de l’extension en transmettant simplement un objet JSON contenant l’identifiant d’un fichier audio.
Une « capacité » fait office de contrat formel entre la logique PHP sous-jacente et toute entité qui demande son exécution. Ce contrat précise les données que la capacité attend en entrée, son objectif et le schéma de données qu’elle renvoie en sortie.
Lorsque vous enregistrez une capacité, celle-ci est ajoutée au registre des capacités de votre site. À partir de ce moment, WordPress agit comme une passerelle sécurisée : il vérifie l’authentification et valide les données entrantes par rapport au schéma établi par le contrat. WordPress ne transmet la requête à la fonction PHP sous-jacente que si la charge utile respecte strictement les termes du contrat.
Une capacité est agnostique. WordPress n’a pas besoin de connaître l’entité spécifique qui demande l’accès ; il vérifie uniquement que la requête est autorisée et qu’elle respecte les contraintes du contrat.
En enregistrant une capacité, votre extension n’est plus seulement une extension dotée de sa propre logique interne ; elle devient un prestataire de services pour l’ensemble de l’écosystème. Qu’il s’agisse d’une application mobile, d’un script d’automatisation tel que Make.com ou Zapier, d’un agent d’IA ou d’un serveur communiquant via le protocole MCP, ces entités sauront exactement comment déclencher des opérations structurées sur votre site.
Utilisation de l’API « Abilities »
L’API « Abilities » fournit un ensemble complet de fonctions qui vous permettent de découvrir les capacités enregistrées sur votre site, de les activer, ainsi que de les enregistrer et de les désenregistrer.
Gérer les capacités de votre site
Vous pouvez récupérer la liste de toutes les capacités enregistrées ou extraire un objet de capacité individuel. Vous pouvez également vérifier certaines conditions, par exemple si une capacité spécifique est enregistrée ou si l’agent dispose des autorisations nécessaires pour la déclencher.
Obtenir la liste des capacités enregistrées sur votre site
La fonction wp_get_abilities() renvoie un tableau contenant toutes les capacités enregistrées. Vous pouvez la tester à l’aide de WP-CLI. Une fois connecté à votre site via SSH, accédez au répertoire racine du site, où se trouve votre fichier wp-config.php, à l’aide des commandes suivantes :
cd /path/to/your/site
ls wp-config.php
Assurez-vous ensuite que WP-CLI reconnaît l’installation de votre site :
wp core is-installed
wp option get siteurl
Si l’URL de votre site s’affiche, vous êtes prêt à exécuter la commande suivante :
wp eval '$abilities = wp_get_abilities(); foreach ( $abilities as $a ) { echo $a->get_name() . PHP_EOL; }'
Cette commande exécute du code PHP dans votre terminal. Le code PHP demande les noms de toutes les fonctionnalités enregistrées sur votre site et, par défaut, devrait fournir la réponse suivante :
core/get-site-info
core/get-user-info
core/get-environment-info
Vous pouvez demander un ensemble de données plus complet à l’aide de la commande suivante :
wp eval '
$all_abilities = wp_get_abilities();
foreach ( $all_abilities as $ability ) {
echo "Ability Name: " . esc_html( $ability->get_name() ) . "n";
echo "Label: " . esc_html( $ability->get_label() ) . "n";
echo "Category: " . esc_html( $ability->get_category() ) . "n";
echo "Description: " . esc_html( $ability->get_description() ) . "n";
echo "---n";
}
'
Lorsque vous exécutez cette commande sur un site WordPress 7.0 vierge, le terminal affiche la réponse suivante :
Ability Name: core/get-site-info
Label: Get Site Information
Category: site
Description: Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.
---
Ability Name: core/get-user-info
Label: Get User Information
Category: user
Description: Returns profile details for the current authenticated user to support personalization, auditing, and access-aware behavior. By default returns all fields, or optionally a filtered subset.
---
Ability Name: core/get-environment-info
Label: Get Environment Info
Category: site
Description: Returns core details about the site's runtime context for diagnostics and compatibility (environment, PHP runtime, database server info, WordPress version). By default returns all fields, or optionally a filtered subset.
---
Récupérer un objet « ability »
La fonction wp_get_ability() renvoie un objet « ability » unique en fonction de son nom. Vous pouvez la tester dans WP-CLI à l’aide de la commande suivante :
wp eval '
$ability = wp_get_ability( "core/get-site-info" );
if ( ! $ability ) {
echo "Ability not found\n";
exit( 1 );
}
echo "Name: " . $ability->get_name() . "\n";
echo "Label: " . $ability->get_label() . "\n";
echo "Category: " . $ability->get_category() . "\n";
echo "Description: " . $ability->get_description() . "\n";
echo "nInput Schema:\n";
var_dump( $ability->get_input_schema() );
echo "nOutput Schema:\n";
var_dump( $ability->get_output_schema() );
echo "nMeta:\n";
var_dump( $ability->get_meta() );
'
Si la capacité est correctement enregistrée sur votre site, vous obtiendrez la réponse suivante dans votre terminal :
Name: core/get-site-info
Label: Get Site Information
Category: site
Description: Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.
Input Schema:
array(4) {
["type"]=>
string(6) "object"
["properties"]=>
array(1) {
["fields"]=>
array(3) {
["type"]=>
string(5) "array"
["items"]=>
array(2) {
["type"]=>
string(6) "string"
["enum"]=>
array(8) {
[0]=>
string(4) "name"
[1]=>
string(11) "description"
[2]=>
string(3) "url"
[3]=>
string(5) "wpurl"
[4]=>
string(11) "admin_email"
[5]=>
string(7) "charset"
[6]=>
string(8) "language"
[7]=>
string(7) "version"
}
}
["description"]=>
string(81) "Optional: Limit response to specific fields. If omitted, all fields are returned."
}
}
["additionalProperties"]=>
bool(false)
["default"]=>
array(0) {
}
}
Output Schema:
array(3) {
["type"]=>
string(6) "object"
["properties"]=>
array(8) {
["name"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(10) "Site Title"
["description"]=>
string(15) "The site title."
}
["description"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(7) "Tagline"
["description"]=>
string(17) "The site tagline."
}
["url"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(18) "Site Address (URL)"
["description"]=>
string(94) "The public URL where visitors access the site. May differ from the WordPress installation URL."
}
["wpurl"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(23) "WordPress Address (URL)"
["description"]=>
string(83) "The URL where WordPress core files are served. May differ from the public site URL."
}
["admin_email"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(28) "Administration Email Address"
["description"]=>
string(37) "The site administrator email address."
}
["charset"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(12) "Site Charset"
["description"]=>
string(28) "The site character encoding."
}
["language"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(13) "Site Language"
["description"]=>
string(42) "The site locale in dash form (e.g. en-US)."
}
["version"]=>
array(3) {
["type"]=>
string(6) "string"
["title"]=>
string(17) "WordPress Version"
["description"]=>
string(48) "The WordPress core version running on this site."
}
}
["additionalProperties"]=>
bool(false)
}
Meta:
array(2) {
["annotations"]=>
array(3) {
["readonly"]=>
bool(true)
["destructive"]=>
bool(false)
["idempotent"]=>
bool(true)
}
["show_in_rest"]=>
bool(true)
}
Vérifier si une capacité est enregistrée
La fonction wp_has_ability() vous permet de vérifier si une capacité est enregistrée. Dans WP-CLI, vous pouvez l’utiliser comme ceci :
wp eval '
if ( wp_has_ability( "core/get-site-info" ) ) {
echo "✓ core/get-site-info is registered\n";
} else {
echo "✗ core/get-site-info not found\n";
}
'
Si la fonctionnalité a été enregistrée, le message suivant s’affichera dans le terminal :
✓ core/get-site-info is registered
Vérifier les autorisations de l’agent
Vous pouvez vérifier si l’utilisateur actuel dispose des autorisations nécessaires pour exécuter une capacité en utilisant la méthode check_permissions() de l’objet $ability. Celle-ci renvoie « true », « false » ou un objet WP_Error. Essayons d’appeler cette méthode depuis le terminal à l’aide de la commande WP-CLI suivante :
wp --user=1 eval '
$ability = wp_get_ability( "core/get-site-info" );
if ( $ability ) {
$has_permissions = $ability->check_permissions();
if ( true === $has_permissions ) {
echo "You have permissions to execute this ability.";
} else {
if ( is_wp_error( $has_permissions ) ) {
error_log( "Permissions check failed: " . $has_permissions->get_error_message() );
}
echo "You do not have permissions to execute this ability.";
}
} else {
echo "Ability not found.";
}
'
Ici, nous avons défini --user=1, c’est pourquoi vous obtiendrez la réponse suivante :
You have permissions to execute this ability.
Enregistrer une capacité
Il est désormais temps d’enregistrer une capacité. Pour illustrer un cas d’utilisation concret, nous allons étendre le plugin décrit dans notre article sur le WordPress AI Client. Ce plugin envoie un fichier audio au modèle d’IA afin d’en extraire le texte et de déclencher la génération de blocs Gutenberg. Dans cette section, nous verrons comment enregistrer ce processus en tant que capacité afin que toute entité disposant des autorisations nécessaires puisse le découvrir et l’utiliser.
Avant d’enregistrer une nouvelle capacité, vous devez enregistrer une nouvelle catégorie de capacité.
Pour cela, vous devrez accrocher la fonction wp_register_ability_category() au hook wp_abilities_api_categories_init.
Cette fonction accepte un slug de catégorie unique et un tableau associatif d’arguments.
Voici comment enregistrer votre catégorie de capacité :
function aicb_register_ability_category(): void {
if ( ! function_exists( 'wp_register_ability_category' ) ) {
return;
}
wp_register_ability_category(
'content-generation',
array(
'label' => 'Content Generation',
'description' => 'AI-powered content transformation and structuring abilities',
)
);
}
add_action( 'wp_abilities_api_categories_init', 'aicb_register_ability_category' );
L’étape suivante consiste à enregistrer la fonctionnalité. Pour ce faire, vous devrez associer la fonction wp_register_ability() à l’action wp_abilities_api_init.
Cette fonction accepte deux arguments : le nom de la fonctionnalité, y compris son espace de noms, et un tableau d’arguments pour la configuration de la fonctionnalité.
Voici l’enregistrement de la fonctionnalité pour l’extension AI Content Builder :
function aicb_register_audio_to_gutenberg_blocks_ability(): void {
if ( ! function_exists( 'wp_register_ability' ) ) {
return;
}
$input_schema = array( ... );
$output_schema = array( ... );
wp_register_ability(
'ai-content-builder/audio-to-gutenberg-blocks',
array(
'category' => 'content-generation',
'label' => 'Audio to Gutenberg Blocks',
'description' => 'Transcribes audio and converts the content into WordPress Gutenberg-compatible block objects.',
'input_schema' => $input_schema,
'output_schema' => $output_schema,
'execute_callback' => 'aicb_audio_to_gutenberg_blocks_callback',
'permission_callback' => static function (): bool {
return current_user_can( 'edit_posts' );
},
'meta' => array(
'show_in_rest' => true,
'annotations' => array(
'readonly' => false,
'destructive' => false,
'idempotent' => false,
'instructions' => 'Processes an audio attachment: transcribes it, generates structured blog content via AI, and returns Gutenberg-ready block objects.',
),
),
)
);
}
add_action( 'wp_abilities_api_init', 'aicb_register_audio_to_gutenberg_blocks_ability' );
Dans l’appel de la fonction wp_register_ability, nous avons configuré les arguments suivants :
category: La catégorie à laquelle appartient la fonctionnalité.label: Le nom d’affichage de la fonctionnalité.description: Une brève description du fonctionnement de la fonctionnalité et de son objectif.input_schema: Le schéma de données pour les arguments d’entrée.output_schema: Le schéma de données fourni et renvoyé par la fonctionnalité.execute_callback: La fonction de rappel à exécuter lorsque la capacité est déclenchée.permission_callback: Une fonction de rappel exécutée pour vérifier que l’agent dispose des autorisations requises pour exécuter la fonctionnalité.meta: Un tableau de champs de métadonnées supplémentaires pour la fonctionnalité.show_in_rest: Détermine s’il convient ou non d’exposer la fonctionnalité au sein de l’API REST de WordPress.annotations: Un tableau d’éléments descriptifs définissant le comportement de la fonctionnalité.
input_schema est un tableau qui définit le contrat d’entrée de la fonctionnalité. Il représente la définition du schéma JSON permettant de valider les données d’entrée de la fonctionnalité. Dans notre cas d’utilisation spécifique, il est défini comme ceci :
$input_schema = array(
'type' => 'object',
'properties' => array(
'audio_id' => array(
'type' => 'integer',
'description' => 'The ID of the audio attachment to process and convert into Gutenberg blocks.',
),
),
'required' => array( 'audio_id' ),
);
Ce schéma JSON représente le format que les données d’entrée doivent respecter pour utiliser cette fonctionnalité.
output_schema correspond au contrat de sortie renvoyé par la fonctionnalité. Dans notre exemple, chaque élément est un objet représentant un bloc JSON :
$output_schema = array(
'type' => 'object',
'properties' => array(
'title' => array( 'type' => 'string' ),
'sections' => array(
'type' => 'array',
'items' => array( 'type' => 'object' ),
),
'blocks' => array(
'type' => 'array',
'items' => array( 'type' => 'object' ),
),
'transcript' => array( 'type' => 'string' ),
),
'required' => array( 'blocks' ),
);
L’étape suivante consiste à définir la fonction de rappel qui s’exécute lorsque la capacité est déclenchée (voir le code complet sur GitHub) :
function aicb_audio_to_gutenberg_blocks_callback( array $args ) {
// missing code
// see GitHub
...
$structured_json = wp_ai_client_prompt( $prompt )
->using_system_instruction( $instructions )
->using_temperature( 0.4 )
->as_json_response( $schema )
->generate_text();
if ( is_wp_error( $structured_json ) ) {
return $structured_json;
}
$structured = json_decode( (string) $structured_json, true );
if ( ! is_array( $structured ) ) {
return new WP_Error(
'invalid_ai_json',
'Could not parse structured AI response.',
array( 'status' => 500 )
);
}
// Normalize the output.
$normalized = aicb_normalize_structured_post( $structured );
if ( '' === $normalized['title'] && empty( $normalized['sections'] ) ) {
return new WP_Error(
'empty_structured_content',
'The AI provider returned empty structured content.',
array( 'status' => 500 )
);
}
// Convert to Gutenberg blocks.
$blocks = aicb_sections_to_blocks( $normalized['title'], $normalized['sections'] );
return $blocks;
}
Cette fonction appelle deux fonctions personnalisées. La première (aicb_normalize_structured_post) normalise la sortie de l’IA dans un format prédéfini et nettoie les données :
function aicb_normalize_structured_post( array $structured ): array {
$title = isset( $structured['title'] )
? sanitize_text_field( (string) $structured['title'] )
: '';
$sections = array();
if ( isset( $structured['sections'] ) && is_array( $structured['sections'] ) ) {
foreach ( $structured['sections'] as $section ) {
if ( ! is_array( $section ) ) {
continue;
}
$heading = isset( $section['heading'] )
? sanitize_text_field( (string) $section['heading'] )
: '';
$level = 2;
$paragraphs = array();
if ( isset( $section['paragraphs'] ) && is_array( $section['paragraphs'] ) ) {
foreach ( $section['paragraphs'] as $paragraph ) {
$clean_paragraph = trim( sanitize_textarea_field( (string) $paragraph ) );
if ( '' !== $clean_paragraph ) {
$paragraphs[] = $clean_paragraph;
}
}
}
$bullet_points = array();
if ( isset( $section['bullet_points'] ) && is_array( $section['bullet_points'] ) ) {
foreach ( $section['bullet_points'] as $bullet_point ) {
$clean_bullet_point = trim( sanitize_text_field( (string) $bullet_point ) );
if ( '' !== $clean_bullet_point ) {
$bullet_points[] = $clean_bullet_point;
}
}
}
if ( '' === $heading || empty( $paragraphs ) ) {
continue;
}
$sections[] = array(
'heading' => $heading,
'level' => $level,
'paragraphs' => $paragraphs,
'bullet_points' => $bullet_points,
);
}
}
return array(
'title' => $title,
'sections' => $sections,
);
}
La fonction accepte un tableau structuré d’objets JSON, normalise et nettoie les données, puis renvoie un tableau contenant le titre et les sections.
La deuxième fonction (aicb_sections_to_blocks) convertit les données normalisées en objets descripteurs de blocs et est définie comme ceci :
function aicb_sections_to_blocks( string $title, array $sections ): array {
$blocks = array();
foreach ( $sections as $section ) {
if ( ! is_array( $section ) ) {
continue;
}
$heading = isset( $section['heading'] ) ? trim( (string) $section['heading'] ) : '';
if ( '' === $heading ) {
continue;
}
$paragraphs = array();
if ( isset( $section['paragraphs'] ) && is_array( $section['paragraphs'] ) ) {
foreach ( $section['paragraphs'] as $paragraph ) {
$clean = trim( (string) $paragraph );
if ( '' !== $clean ) {
$paragraphs[] = $clean;
}
}
}
if ( empty( $paragraphs ) ) {
continue;
}
$blocks[] = array(
'name' => 'core/heading',
'attributes' => array(
'content' => $heading,
'level' => 2,
),
);
foreach ( $paragraphs as $paragraph ) {
$blocks[] = array(
'name' => 'core/paragraph',
'attributes' => array(
'content' => $paragraph,
),
);
}
if ( isset( $section['bullet_points'] ) && is_array( $section['bullet_points'] ) ) {
$bullet_items_html = '';
foreach ( $section['bullet_points'] as $bullet_point ) {
$clean_bullet = trim( sanitize_text_field( (string) $bullet_point ) );
if ( '' === $clean_bullet ) {
continue;
}
// core/list expects HTML in the `values` attribute.
$bullet_items_html .= '<li>' . esc_html( $clean_bullet ) . '</li>';
}
if ( '' !== $bullet_items_html ) {
$blocks[] = array(
'name' => 'core/list',
'attributes' => array(
'values' => '<ul>' . $bullet_items_html . '</ul>',
),
);
}
}
}
return $blocks;
}
Voici les principaux points forts de cette fonction :
- La fonction accepte deux arguments : une chaîne de caractères représentant le titre de l’article et un tableau contenant les sections générées par le modèle d’IA.
- Pour chaque section, la fonction génère un titre et au moins un paragraphe.
- Si des puces sont présentes, elle génère un nombre correspondant d’éléments de liste.
- La fonction renvoie un tableau
$blocksd’objets descripteurs de blocs, qui correspond au contrat de sortie renvoyé par la capacité ($output_schema).
Notez que la sortie de la fonction n’est pas le balisage brut des blocs. Celui-ci sera généré côté client à l’aide de la fonction JavaScript createBlock.
Par exemple, l’élément de titre d’une section est représenté par l’objet suivant :
if ( '' !== $heading ) {
$blocks[] = array(
'name' => 'core/heading',
'attributes' => array(
'content' => $heading,
'level' => ( 3 === $level ) ? 3 : 2,
),
);
}
Une fois votre fonctionnalité enregistrée, vous pouvez exécuter dans votre terminal les mêmes commandes WP-CLI que celles présentées ci-dessus pour obtenir les détails. Le code suivant générera le schéma d’entrée de votre fonctionnalité :
wp --user=1 eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not found\n";
exit( 1 );
}
echo "Input Schema:\n";
var_dump( $ability->get_input_schema() );
'
Voici le résultat affiché dans le terminal :
Input Schema:
array(3) {
["type"]=>
string(6) "object"
["properties"]=>
array(1) {
["audio_id"]=>
array(2) {
["type"]=>
string(7) "integer"
["description"]=>
string(76) "The ID of the audio attachment to process and convert into Gutenberg blocks."
}
}
["required"]=>
array(1) {
[0]=>
string(8) "audio_id"
}
}
De la même manière, vous pouvez récupérer le schéma de sortie de la capacité :
wp --user=1 eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not found\n";
exit( 1 );
}
echo "Output Schema:\n";
var_dump( $ability->get_output_schema() );
'
Vous pouvez également afficher l’objet complet de votre capacité à l’aide de la commande suivante :
wp eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not found\n";
exit( 1 );
}
echo "Name: " . $ability->get_name() . "\n";
echo "Label: " . $ability->get_label() . "\n";
echo "Category: " . $ability->get_category() . "\n";
echo "Description: " . $ability->get_description() . "\n";
echo "nInput Schema:n\";
var_dump( $ability->get_input_schema() );
echo "nOutput Schema:n\";
var_dump( $ability->get_output_schema() );
'
Exécution d’une capacité
Pour exécuter une fonctionnalité, vous utiliserez la méthode execute() de l’objet $ability. Vous pouvez essayer d’exécuter le code PHP suivant via WP-CLI pour déclencher la fonctionnalité core/get-site-info :
wp --user=1 eval '
$ability = wp_get_ability( "core/get-site-info" );
if ( ! $ability ) {
echo "Ability not found\n";
exit(1);
}
$result = $ability->execute();
if ( is_wp_error( $result ) ) {
echo "ERROR: " . $result->get_error_message() . "n";
exit(1);
}
echo json_encode( $result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "n";
'
Lorsque vous exécutez cette commande, la fonctionnalité renvoie un objet JSON similaire à celui-ci :
{
"name": "WordPress 7.0",
"description": "",
"url": "http://yoursite.kinsta.cloud",
"wpurl": "http://yoursite.kinsta.cloud",
"admin_email": "[email protected]",
"charset": "UTF-8",
"language": "en-US",
"version": "7.1-alpha-62550"
}
Ce qui précède n’est qu’un simple exemple de capacité fournissant des données à votre site.
Comme mentionné ci-dessus, une fonctionnalité peut nécessiter des données d’entrée, effectuer des opérations sur ces données et renvoyer un résultat structuré. Nous pouvons en voir un exemple avec la fonctionnalité que nous avons enregistrée dans la section précédente.
Toujours dans votre terminal, accédez au répertoire racine de votre site et exécutez le code PHP suivant :
wp --user=1 eval '
$ability = wp_get_ability( "ai-content-builder/audio-to-gutenberg-blocks" );
if ( ! $ability ) {
echo "Ability not found\n";
exit( 1 );
}
$input = array( "audio_id" => 1755 );
$result = $ability->execute( $input );
if ( is_wp_error( $result ) ) {
echo "ERROR: " . $result->get_error_message() . "\n";
exit( 1 );
}
echo json_encode( $result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) . "n";
'
La méthode execute transmet les données d’entrée structurées à la fonctionnalité, qui renvoie un tableau d’objets prêts à être convertis en blocs Gutenberg :
[
{
"name": "core/heading",
"attributes": {
"content": "A Well-Deserved Rest Day in Marrakech",
"level": 2
}
},
{
"name": "core/paragraph",
"attributes": {
"content": "On April 24th, our group of seven motorcyclists took a break from the open road..."
}
},
{
"name": "core/heading",
"attributes": {
"content": "Exploring Jemaa el-Fnaa and the Medina",
"level": 2
}
},
{
"name": "core/paragraph",
"attributes": {
"content": "Our journey led us straight to Jemaa el-Fnaa, the legendary main square of Marrakech..."
}
},
{
"name": "core/list",
"attributes": {
"values": "<ul><li>Navigating the bustling souks and narrow alleys of the ancient Medina.</li><li>Savoring traditional Moroccan and Berber dishes.</li><li>Experiencing the vibrant street performances and food stalls of Jemaa el-Fnaa at night.</li></ul>"
}
},
...
]
Intégration de l’API REST
L’API « Abilities » de WordPress fournit une structure de routage unifiée qui permet à des agents externes d’interroger par programmation les catégories de capacités disponibles (/categories), d’inspecter des contrats de capacités spécifiques (/abilities/{name}) et d’exécuter une capacité spécifique à l’aide du point de terminaison standard « run » (/abilities/{name}/run).
Voici, par exemple, une requête GET qui renvoie la liste des catégories de notre site de test :
https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/categories

Lorsque nous avons enregistré la fonctionnalité dans l’exemple précédent, nous avons défini le paramètre show_in_rest sur true. Ce faisant, nous avons rendu notre fonctionnalité automatiquement accessible via ces points de terminaison natifs de l’API REST de WordPress, sous l’espace de noms centralisé « core » (wp-abilities/v1).
Cela signifie que vous n’avez pas besoin d’enregistrer manuellement des routes personnalisées à partir de zéro pour appeler une capacité depuis un environnement externe. Les agents externes peuvent découvrir et exécuter votre capacité à l’aide de requêtes HTTP standard.
Vous pouvez consulter le contrat spécifique de notre capacité à l’aide de la requête GET suivante :
https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/abilities/ai-content-builder/audio-to-gutenberg-blocks
Enfin, vous pouvez déclencher la fonctionnalité à l’aide d’une requête POST authentifiée :
https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/abilities/ai-content-builder/audio-to-gutenberg-blocks/run
Lorsque vous envoyez ce type de requête, veillez à avoir spécifié les données d’entrée. Dans notre exemple, nous avons défini le JSON suivant dans le corps de la requête :
{
"input": {
"audio_id": YOUR_AUDIO_ID
}
}

Notre fonctionnalité a traité le fichier audio et l’a transmis au modèle d’IA configuré sur le site. Le modèle a renvoyé une sortie structurée qui a ensuite été normalisée et nettoyée, pour finalement renvoyer le tableau d’objets suivant contenant les attributs du bloc :
{
"blocks": [
{
"name": "core/heading",
"attributes": { "content": "A Welcome Rest Day in Marrakech", "level": 2 }
},
{
"name": "core/paragraph",
"attributes": { "content": "On April 24, our group of seven motorcyclists paused our journey..." }
}
]
}
Et c’est précisément le résultat que nous recherchions.
L’avenir de WordPress est « agentique »
Alors que l’AI Client et la nouvelle architecture de connecteurs intègrent des capacités de traitement de l’IA au sein de WordPress, l’API Abilities redéfinit la manière dont WordPress interagit avec le monde extérieur. Nous assistons à un changement de paradigme radical, passant d’une architecture web traditionnelle — reposant sur une interaction manuelle de l’utilisateur où chaque intégration nécessitait des points de terminaison personnalisés et un mappage manuel — à une architecture orientée intention, conçue dès le départ pour l’automatisation.
Pour les développeurs WordPress, la nouvelle API Abilities représente un tournant architectural, caractérisé par le découplage des fonctionnalités des plugins qui contiennent leur logique, le renforcement de la sécurité via le contrat d’entrée/sortie, et la mise en place d’une interopérabilité native à l’échelle de l’ensemble de l’écosystème.
Prises dans leur ensemble, ces fonctionnalités garantissent que l’API Abilities n’est pas simplement une API de plus, mais un véritable moteur d’exécution distribué qui offre un aperçu d’un avenir de plus en plus « agentique » pour WordPress.