De Abilities API, geïntroduceerd in WordPress 6.9, zorgt voor een gemeenschappelijke taal, waardoor alle WordPress-onderdelen – zowel de kern als plugins – hun functionaliteit op een uniforme, begrijpelijke manier kunnen aanbieden, zowel voor mensen als voor machines. Hierdoor is je WordPress site klaar voor integratie met externe automatiseringstools op een gestandaardiseerde en veilige manier.

Als je je afvraagt hoe sommige toepassingen van de Abilities API eruit zouden kunnen zien: denk bijvoorbeeld aan een AI-model dat een gebruiker door het aankoopproces loodst en hem of haar zelfs in staat stelt de aankoop af te ronden zonder je e-commercewebsite te bezoeken. Of denk aan een CI/CD-pijplijn op GitHub Actions die tekst verwerkt die uit een audio- of videobestand is gehaald en deze naar WordPress stuurt voor publicatie. De toepassingen zijn eindeloos.

De Abilities API verandert de rol van WordPress binnen het ecosysteem fundamenteel. Het is niet langer alleen een blog, en zelfs geen CMS meer; tegenwoordig fungeert WordPress als een gedistribueerde uitvoeringsengine die van buitenaf kan worden aangestuurd, als een soort besturingssysteem, helemaal klaar voor autonome agents.

Nieuwsgierig geworden? Tijd om er in te duiken!

Waarvoor is een ability bedoeld?

Een ability is een vindbare, bruikbare functionaliteit op een WordPress site die specifieke bewerkingen mogelijk maakt voor externe entiteiten (zoals AI-modellen) of interne componenten.

De API kan bijvoorbeeld worden gebruikt voor:

  • Het zoeken naar content of het uitvoeren van specifieke databasebewerkingen
  • Het lezen van configuratie-instellingen van de site
  • Een bericht aanmaken
  • Een JSON-structuur omzetten in Gutenberg-blokken

Een ability beschikbaar maken betekent dat je een specifieke functionaliteit interoperabel maakt. Voordat een ability ontdekt en gebruikt kan worden, moet deze worden geregistreerd in een centrale catalogus. Pas dan kunnen WordPress en AI-modellen het ontdekken, de bedoeling ervan begrijpen en het aanroepen wanneer dat nodig is.

Standaard is de functionaliteit van je plugins volledig geïsoleerd. Door een ability te registreren, geef je aan dat de onderliggende logica beschikbaar is als een service voor het hele ecosysteem.

Laten we eens naar een voorbeeld kijken. Als je plugin een functie heeft die een initieel JSON-object omzet in gestructureerde content die klaar is voor Gutenberg-blokken, kun je die als ability registreren. Hierdoor kunnen andere tools met de benodigde rechten precies dezelfde functie activeren.

In onze vorige tutorial over de WordPress AI Client zorgde de plugin voor de kernlogica van het versturen van een audiobestand naar het AI-model, dat een JSON-gestructureerd antwoord teruggaf om Gutenberg-blokken te genereren. Die functionaliteit bleef echter beperkt tot onze plugin. Door dit proces als ability te registreren, ontkoppel je de uitvoering, en kan elke externe entiteit de volledige logica van de plugin activeren door simpelweg een JSON-object door te geven dat een audiobestands-ID bevat.

Een ability fungeert als een formeel contract tussen de onderliggende PHP-logica en elke entiteit die de uitvoering ervan aanvraagt. Het contract specificeert de gegevens die de ability als invoer verwacht, de bedoeling ervan en het gegevensschema dat het als uitvoer retourneert.

Als je een ability registreert, wordt deze toegevoegd aan het ability-register van je site. Vanaf dat moment fungeert WordPress als een veilige gateway: het controleert de authenticatie en valideert binnenkomende gegevens aan de hand van het schema dat in het contract is vastgelegd. WordPress stuurt het verzoek alleen door naar de onderliggende PHP-functie als de payload strikt voldoet aan het contract.

Een ability is agnostisch. WordPress hoeft niet te weten welke specifieke entiteit toegang vraagt; het controleert alleen of het verzoek geautoriseerd is en voldoet aan de voorwaarden van het contract.

Door een ability te registreren, is je plugin niet langer alleen maar een uitbreiding met zijn eigen interne logica; het wordt een dienstverlener voor het hele ecosysteem. Of het nu gaat om een mobiele app, een automatiseringsscript zoals Make.com of Zapier, een AI-agent of een server die via het MCP-protocol communiceert: deze entiteiten weten precies hoe ze gestructureerde bewerkingen op je site moeten activeren.

Werken met de Abilities API

De Abilities API biedt een uitgebreide set functies waarmee je geregistreerde abilities op je site kunt ontdekken, ze kunt activeren en abilities kunt registreren of deregistreren.

Werk met de abilities van je site

Je kunt een lijst opvragen van alle geregistreerde abilities of een afzonderlijk ability-object ophalen. Je kunt ook voorwaarden controleren, zoals of een specifieke ability is geregistreerd of dat de agent de rechten heeft om deze te activeren.

Een lijst ophalen van de abilities die op je site zijn geregistreerd

De functie wp_get_abilities() geeft een array terug met alle geregistreerde abilities. Je kunt dit testen met WP-CLI. Zodra je via SSH verbinding hebt gemaakt met je site, ga je naar de hoofdmap van de site, waar je wp-config.php bestand staat, met de volgende commando’s:

cd /path/to/your/site
ls wp-config.php

Zorg er vervolgens voor dat WP-CLI je site-installatie herkent:

wp core is-installed
wp option get siteurl

Als je de URL van je site te zien krijgt, ben je klaar om de volgende opdracht uit te voeren:

wp eval '$abilities = wp_get_abilities(); foreach ( $abilities as $a ) { echo $a->get_name() . PHP_EOL; }'

Dit commando voert PHP-code uit in je terminal. De PHP-code vraagt de namen op van alle geregistreerde abilities op je site, en standaard zou je het volgende antwoord moeten krijgen:

core/get-site-info
core/get-user-info
core/get-environment-info

Je kunt een completere set gegevens opvragen met het volgende commando:

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";
}
'

Als je dit commando uitvoert op een nieuwe WordPress 7.0 site, geeft de terminal het volgende antwoord weer:

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

Een ability-object ophalen

De functie wp_get_ability() geeft één ability-object terug op basis van de naam. Je kunt dit in WP-CLI testen met het volgende commando:

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() );
'

Als de ability correct op je site is geregistreerd, krijg je het volgende antwoord in je 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)
}

Controleren of een ability is geregistreerd

Met de functie wp_has_ability() kun je controleren of een ability is geregistreerd. In WP-CLI kun je deze als volgt gebruiken:

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";
}
'

Als de ability is geregistreerd, verschijnt het volgende bericht in de terminal:

✓ core/get-site-info is registered

De rechten van de gebruiker controleren

Je kunt controleren of de huidige gebruiker de rechten heeft om een ability uit te voeren door de methode check_permissions() van het $ability-object te gebruiken. Dit geeft true, false of een WP_Error-object terug. Laten we deze methode eens aanroepen vanaf de terminal met de volgende WP-CLI-opdracht:

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.";
}
'

Hier hebben we --user=1 ingesteld, en daarom krijg je het volgende antwoord:

You have permissions to execute this ability.

Een ability registreren

Het is nu tijd om een ability te registreren. Om een praktijkvoorbeeld te laten zien, breiden we de plugin uit die we in ons artikel over de WordPress AI Client hebben beschreven. De plugin stuurt een audiobestand naar het AI-model om de tekst eruit te halen en het genereren van Gutenberg-blokken te activeren. In dit gedeelte bekijken we hoe je dit proces als ability kunt registreren, zodat elke entiteit met de benodigde rechten het kan vinden en gebruiken.

Voordat je een nieuwe ability registreert, moet je eerst een nieuwe ability-categorie aanmaken.

Hiervoor moet je de functie wp_register_ability_category() koppelen aan de hook wp_abilities_api_categories_init.

De functie accepteert een unieke categorie-slug en een associatieve array met argumenten.

Zo registreer je je ability-categorie:

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' );

De volgende stap is het registreren van de ability. Hiervoor koppel je de functie wp_register_ability() aan de actie wp_abilities_api_init.

De functie accepteert twee argumenten: de naam van de ability, inclusief de namespace, en een array met argumenten voor de configuratie van de ability.

Hier is de registratie van de ability voor de AI Content Builder-plugin:

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' );

In de functie-call wp_register_ability hebben we de volgende argumenten geconfigureerd:

  • category: De categorie waartoe de ability behoort.
  • label: De weergavenaam van de ability.
  • description: Een korte beschrijving van wat de ability doet en waarvoor hij dient.
  • input_schema: Het gegevensschema voor de inkomende invoerargumenten.
  • output_schema: Het gegevensschema dat door de ability wordt geleverd en teruggestuurd.
  • execute_callback: De callback-functie die wordt uitgevoerd wanneer de ability wordt geactiveerd.
  • permission_callback: Een callback-functie die controleert of de agent de benodigde rechten heeft om de ability uit te voeren.
  • meta: Een array met extra metadatavelden voor de ability.
  • show_in_rest: Bepaalt of de ability al dan niet beschikbaar wordt gesteld binnen de WordPress REST API.
  • annotations: Een array met beschrijvende elementen die het gedrag van de ability definiëren.

input_schema is een array die het invoercontract van de ability definieert. Het vertegenwoordigt de JSON Schema-definitie voor het valideren van de invoer van de ability. In ons specifieke geval is het als volgt gedefinieerd:

$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' ),
);

Dit JSON-schema geeft het formaat weer dat de invoergegevens moeten volgen om deze ability te kunnen gebruiken.

output_schema is het uitvoercontract dat door de ability wordt geretourneerd. In ons voorbeeld is elk item een object dat een JSON-blok vertegenwoordigt:

$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' ),
);

De volgende stap is het definiëren van de callback-functie die wordt uitgevoerd wanneer de ability wordt geactiveerd (bekijk de volledige code op 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;
}

Deze functie roept twee custom functies aan. De eerste (aicb_normalize_structured_post) normaliseert de uitvoer van de AI naar een vooraf gedefinieerd formaat en zuivert de gegevens:

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,
	);
}

De functie accepteert een gestructureerde array van JSON-objecten, normaliseert en zuivert de gegevens, en retourneert een array met de titel en de secties.

De tweede functie (aicb_sections_to_blocks) zet de genormaliseerde gegevens om in blokdescriptor-objecten en is als volgt gedefinieerd:

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;
}

Dit zijn de belangrijkste kenmerken van deze functie:

  • De functie neemt 2 argumenten aan: een string die de titel van het bericht weergeeft en een array met de secties die door het AI-model zijn gegenereerd.
  • Voor elke sectie genereert de functie een kop en minstens één alinea.
  • Als er opsommingstekens zijn, genereert de functie een overeenkomstig aantal lijstitems.
  • De functie retourneert een $blocks-array met blokdescriptor-objecten; dit is het outputcontract dat door de ability ($output_schema) wordt teruggestuurd.

Let op: de uitvoer van de functie is niet de ruwe blokopmaak. Deze wordt aan de clientzijde gegenereerd met behulp van de JavaScript-functie createBlock.

Het kopelement van een sectie wordt bijvoorbeeld weergegeven door het volgende object:

if ( '' !== $heading ) {
	$blocks[] = array(
		'name'       => 'core/heading',
		'attributes' => array(
			'content' => $heading,
			'level'   => ( 3 === $level ) ? 3 : 2,
		),
	);
}

Zodra je je ability hebt geregistreerd, kun je dezelfde WP-CLI-commando’s als hierboven in je terminal uitvoeren om de details op te vragen. De volgende code genereert het invoerschema voor je ability:

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() );
'

Dit is het resultaat in de 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"
	}
}

Op dezelfde manier kun je het outputschema van de ability opvragen:

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() );
'

Je kunt ook het volledige object van je ability weergeven met de volgende opdracht:

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() );
'

Een ability uitvoeren

Om een ability uit te voeren, gebruik je de methode execute() van het $ability-object. Probeer eens de volgende PHP-code via WP-CLI uit te voeren om de ability core/get-site-info te activeren:

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";
'

Als je dit commando uitvoert, levert de ability een JSON-object op dat er ongeveer zo uitziet:

{
	"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"
}

Het bovenstaande is slechts een eenvoudig voorbeeld van een ability die gegevens voor je site levert.

Zoals hierboven vermeld, kan een ability invoergegevens vereisen, bewerkingen op die gegevens uitvoeren en een gestructureerde uitvoer retourneren. We kunnen hier een voorbeeld van zien met de ability die we in de vorige paragraaf hebben geregistreerd.

Blijf in je terminal, ga naar de hoofdmap van je site en voer de volgende PHP-code uit:

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";
'

De methode execute geeft de gestructureerde invoergegevens door aan de ability, die een array met objecten teruggeeft die klaar zijn om te worden omgezet in Gutenberg-blokken:

[
	{
		"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>"
		}
	},
	...
]

REST API-integratie

De WordPress Abilities API biedt een uniforme routingstructuur waarmee externe agents programmatisch beschikbare ability-categorieën kunnen opvragen (/categories), specifieke ability-contracten kunnen bekijken (/abilities/{name}) en een specifieke ability kunnen uitvoeren via het standaard run-endpoint (/abilities/{name}/run).

Hier is bijvoorbeeld een GET-verzoek dat de lijst met categorieën van onze testsite teruggeeft:

https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/categories
GET-verzoek voor ability-categorieën in Postman.
Alle verzoeken moeten worden geautoriseerd.

Toen we de ability in het vorige voorbeeld registreerden, hebben we de parameter show_in_rest ingesteld op true. Hierdoor hebben we onze ability automatisch toegankelijk gemaakt via deze native WordPress REST API-endpoints onder de gecentraliseerde kernnaamruimte (wp-abilities/v1).

Dit betekent dat je geen custom routes helemaal zelf hoeft te registreren om een ability vanuit een externe omgeving aan te roepen. Externe agents kunnen je ability vinden en uitvoeren met standaard HTTP-verzoeken.

Je kunt het specifieke contract van onze ability bekijken met het volgende GET-verzoek:

https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/abilities/ai-content-builder/audio-to-gutenberg-blocks

Ten slotte kun je de ability activeren met een geauthenticeerd POST-verzoek:

https://yoursite.kinsta.cloud/wp-json/wp-abilities/v1/abilities/ai-content-builder/audio-to-gutenberg-blocks/run

Zorg er bij het versturen van dit soort verzoeken voor dat je de invoergegevens hebt opgegeven. Voor ons voorbeeld hebben we de volgende JSON in de verzoektekst gezet:

{
	"input": {
		"audio_id": YOUR_AUDIO_ID
	}
}
Een ability uitvoeren via een HTTP-verzoek in Postman.
Een ability uitvoeren via een HTTP-verzoek in Postman.

Onze ability heeft de audio verwerkt en doorgestuurd naar het AI-model dat op de site is geconfigureerd. Het model leverde een gestructureerde uitvoer op die vervolgens werd genormaliseerd en opgeschoond, waarna uiteindelijk de volgende reeks objecten werd teruggestuurd met daarin de blokattributen:

{
	"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..." }
		}
	]
}

En dit is precies het resultaat waar we op mikten.

De toekomst van WordPress is agentisch

Terwijl de AI Client en de nieuwe connectorarchitectuur AI-verwerkingsmogelijkheden binnen WordPress brengen, geeft de Abilities API een nieuwe invulling aan hoe WordPress met de buitenwereld omgaat. We zijn getuige van een drastische paradigmaverschuiving: van een traditionele webarchitectuur — gebaseerd op handmatige gebruikersinteractie waarbij elke integratie custom endpoints en handmatige mapping vereiste — naar een intentiegestuurde architectuur die vanaf de basis is ontworpen voor automatisering.

Voor WordPress-ontwikkelaars betekent de nieuwe Abilities API een architectonisch keerpunt, gekenmerkt door het loskoppelen van functionaliteit van plugins die de logica ervan bevatten, het waarborgen van beveiliging via het input/output-contract en het mogelijk maken van native interoperabiliteit in het hele ecosysteem.

Al deze kenmerken samen zorgen ervoor dat de Abilities API niet zomaar een API is, maar een echte gedistribueerde uitvoeringsengine die een glimp biedt van een toekomst waarin WordPress steeds meer op eigen kracht gaat werken.

Carlo Daniele Kinsta

Carlo is een gepassioneerd liefhebber van webdesign en front-end development. Hij werkt al meer dan 10 jaar met WordPress, ook in samenwerking met Italiaanse en Europese universiteiten en onderwijsinstellingen. Hij heeft tientallen artikelen en gidsen over WordPress geschreven, gepubliceerd op zowel Italiaanse als internationale websites en in gedrukte tijdschriften. Je kunt Carlo vinden op X en LinkedIn.