Categorieën
WordPress

WordPress koppelen aan AI met MCP

Ik ben de afgelopen tijd wat aan het experimenteren met het koppelen van WordPress-installaties aan AI-chatapps. Het idee is interessant: niet alleen een AI-chatbot over je website laten praten, maar een AI-client daadwerkelijk toegang geven tot WordPress via het Model Context Protocol (MCP).

WordPress heeft daar sinds versie 7.1 ook steeds meer bouwstenen voor gekregen. Daarmee wordt het interessanter om WordPress als databron of zelfs als onderdeel van een AI-workflow te gebruiken.

Maar voordat je zover bent, moet je natuurlijk eerst verbinding maken.

En daar liep ik tegen een probleem aan.

Even terug naar augustus

Op 18 augustus deed ik een eerste poging om een WordPress-installatie via MCP aan Claude Desktop te koppelen. Ik had inmiddels wat gelezen over MCP en OAuth en het leek allemaal redelijk overzichtelijk.

De WordPress-kant had alleen nog geen standaard MCP-server die je zomaar kunt activeren. Ik volg verschillende Nederlandse WordPress-ontwikkelaars op social media en zo was ik eerder ook de Albert AI Butler plugin van Mark Jansen van YourMark tegengekomen.

De plugin zag er technisch interessant uit en het uitgangspunt was eigenlijk precies wat ik zocht: een MCP-server voor WordPress, inclusief OAuth-authenticatie.

Het idee was simpel:

  1. Installeer Albert op een WordPress-site.
  2. Gebruik de MCP-server-URL in je AI-client.
  3. De client ontdekt dat authenticatie nodig is.
  4. Je logt in op WordPress.
  5. Klaar.

Dat klonk goed.

In de praktijk was het minder eenvoudig.

Ik heb verschillende clients geprobeerd, waaronder Claude Desktop, de ChatGPT desktop-app, Jan en Open WebUI. Met een WordPress Application Password kreeg ik sommige dingen wel aan de praat, maar voor een minder technisch persoon is dat niet bepaald de ideale gebruikerservaring.

OAuth is hier veel logischer.

Alleen kreeg ik die OAuth-flow niet goed werkend.

“Dit zou toch gewoon moeten werken?”

Op 9 september kwam ik een post van Remkus de Vries tegen over precies dit onderwerp:

Daarin werd ook Albert AI Butler genoemd.

Dat maakte me opnieuw nieuwsgierig. Als dit inmiddels daadwerkelijk gebruikt en beschreven wordt, zou de OAuth-flow toch gewoon moeten werken?

Ik besloot het nog eens te proberen.

Dat leverde onder andere deze melding op in Claude:

Couldn’t register with sign-in service.

Ik begon daarom wat verder te graven en kwam uiteindelijk ook bij de MCP Inspector terecht. Dat hielp om iets beter te begrijpen wat er achter de schermen allemaal gebeurt, maar ik was zelf nog relatief nieuw met MCP en OAuth.

Dus op 14 september besloot ik Mark maar eens een berichtje te sturen.

Even de maker vragen

Ik ken Mark een beetje vanuit de WordPress-community. We hadden elkaar eerder gesproken via de WordPress Nederland Slack (wpnl.slack.com), dus ik stuurde hem daar een bericht met mijn bevindingen.

Mijn eerste vraag was eigenlijk heel simpel: zou Cloudflare of SiteGround misschien roet in het eten gooien?

Ik gaf hem mijn MCP-endpoint en de foutmelding uit Claude.

Mark gebruikte zelf primair Claude Desktop als MCP-client en dook er direct in. Al snel bleek dat Claude ondertussen iets aan zijn kant had veranderd in de manier waarop custom connectors en OAuth worden afgehandeld.

Dat was interessant, maar nog geen verklaring waarom het bij mij niet werkte.

We testten vervolgens een demo-installatie van Albert. Met de demo-URL kon ik wel door de OAuth-flow heen.

Claude stuurde me naar de Claude-loginpagina en daarna leek de flow verder goed te gaan.

Daarmee werd het zoekgebied kleiner.

Het zat dus waarschijnlijk niet fundamenteel in Albert, Claude of OAuth.

Wat was dan het verschil tussen de demo en mijn eigen WordPress-installatie?

Hallo /.well-known/

Bij OAuth en MCP spelen een aantal discovery-endpoints een belangrijke rol. Een client kan daarmee automatisch ontdekken waar authenticatie geregeld wordt en welke endpoints daarvoor beschikbaar zijn.

Een van die endpoints zit onder:

/.well-known/

En laat dat nou net een directory zijn waar SiteGround zelf iets mee doet.

Ik testte bijvoorbeeld:

https://www.remcotolsma.nl/.well-known/oauth-protected-resource

Maar in plaats van de JSON-response van WordPress kreeg ik een SiteGround 404.

Ik heb SiteGround vervolgens gevraagd hoe zij omgaan met /.well-known/.

Het antwoord kwam, zoals dat tegenwoordig vaker gaat, van de AI-supportbot.

De uitleg kwam er kort gezegd op neer dat SiteGround een Nginx reverse proxy gebruikt die verzoeken naar /.well-known/ rechtstreeks probeert af te handelen. Als er geen fysiek bestand op de server staat, krijgt de request een 404 voordat Apache of WordPress überhaupt aan de beurt komt.

De voorgestelde oplossing was dan ook: maak de benodigde JSON-bestanden fysiek aan in public_html/.well-known/.

Technisch gezien zou dat kunnen werken.

Maar dat voelde niet als een oplossing die je wilt voorschrijven voor een WordPress-plugin.

Een WordPress-plugin die bij installatie bestanden in een specifieke directory op de server moet gaan schrijven, alleen omdat een hostingplatform /.well-known/ op een bepaalde manier afhandelt, opent weer een hele nieuwe doos met problemen.

Zoals Mark het verwoordde:

“Opening up a whole other can of worms haha”

Daar was ik het wel mee eens.

Een andere route

Mark ging verder zoeken in de MCP-specificatie en de manier waarop clients discovery uitvoeren.

Daar bleek een interessante mogelijkheid te zitten.

Een goede MCP-client kan discovery in meerdere stappen uitvoeren. De /.well-known/-routes hoeven daarbij niet noodzakelijk rechtstreeks in de root van het domein te staan.

Mark paste Albert daarop aan.

In plaats van de discovery-informatie op een plek te zetten die door veel hostingplatforms wordt onderschept, werd het pad aangepast zodat de benodigde /.well-known/-informatie onder een subdirectory van de MCP-server beschikbaar komt.

Mark stuurde me vervolgens een beta van versie 1.4.1 om te testen.

Ik installeerde hem op mijn site, koppelde dezelfde MCP-server opnieuw aan Claude en dit keer werkte de OAuth-flow wel.

Geen Application Password, geen handmatig geknutsel met OAuth-gegevens. Gewoon de MCP-server-URL toevoegen, OAuth laten detecteren en door de login-flow heen.

Precies zoals ik in eerste instantie verwachtte dat het zou werken.

Van probleem naar release

De wijziging is uiteindelijk onderdeel geworden van Albert AI Butler 1.4.1.

Interessant daarbij is dat het probleem niet specifiek voor SiteGround bleek te zijn. Tijdens het testen bleek dat Remkus tegen een vergelijkbaar probleem aanliep bij Servebolt. Ook daar werkte de aangepaste oplossing.

Mijn experiment met MCP had daarmee niet alleen op mijn eigen installatie resultaat.

Wat dit voor WordPress interessant maakt

Voor mij wordt het vanaf hier eigenlijk interessanter.

De MCP-koppeling is één ding, maar uiteindelijk gaat het natuurlijk om wat je ermee kunt doen.

WordPress heeft inmiddels ook een Abilities API. Daarmee kunnen plugins functionaliteit op een gestandaardiseerde manier beschikbaar stellen aan andere systemen. In combinatie met MCP wordt dat interessant voor AI-clients.

Dat betekent bijvoorbeeld dat je niet alleen algemene WordPress-functionaliteit beschikbaar kunt maken, maar ook functionaliteit uit je eigen plugins.

Dat is voor mij een stuk interessanter dan alleen vragen stellen over pagina’s en berichten.

Zo hebben we voor een klant bijvoorbeeld een behoorlijk complexe Twinfield-schaduwdatabase binnen WordPress gebouwd. Daarin wordt financiële informatie uit Twinfield verwerkt en beschikbaar gemaakt voor de applicatie die we rondom WordPress hebben gebouwd.

Als je daar vervolgens relevante abilities voor definieert, ontstaat ineens de mogelijkheid om vanuit een AI-client vragen te stellen over die Twinfield-data.

Bijvoorbeeld niet alleen:

“Welke berichten staan er op mijn website?”

maar veel meer richting:

“Welke ontwikkelingen zie je in de financiële gegevens van deze administratie?”

Of:

“Welke transacties vallen op als ik de afgelopen periode vergelijk met dezelfde periode vorig jaar?”

Daarmee wordt WordPress niet alleen een CMS waar een AI-client toevallig wat data uit kan lezen. Het kan ook een interface worden naar functionaliteit en data die specifiek voor een bepaalde toepassing in WordPress is gebouwd.

En dat vind ik een stuk interessanter.

Zeker omdat systemen als Twinfield zelf op dit vlak nog lang niet altijd dezelfde mogelijkheden bieden. Als je de relevante data al via een eigen WordPress-applicatie beschikbaar hebt, kun je daar met abilities en MCP een nieuwe interface bovenop zetten.

Eerst maar eens verder experimenteren

Mijn eerste doel was eigenlijk vrij bescheiden: een WordPress-installatie koppelen aan Claude via MCP.

Dat bleek iets meer uitzoekwerk te zijn dan verwacht.

Uiteindelijk leverde het wel een werkende OAuth-koppeling op, een verbetering aan Albert AI Butler en voor mij vooral een beter beeld van hoe MCP, OAuth, WordPress en hosting zich tot elkaar verhouden.

De volgende stap is voor mij dan ook niet zozeer nóg een WordPress-installatie aan Claude koppelen.

Ik ben vooral benieuwd wat er gebeurt als je eigen WordPress-plugins functionaliteit beschikbaar gaan stellen via de Abilities API en je die vervolgens via MCP aan een AI-client kunt aanbieden.

Daar begint het wat mij betreft pas echt interessant te worden.

Categorieën
PHP WordPress

Bug met `style_handle` bij block styles in WordPress

De WordPress-thema’s die we tegenwoordig bij Pronamic ontwikkelen, zijn doorgaans volledig opgebouwd met blokken. We zetten daarbij ook steeds meer in op Full Site Editing (FSE)-thema’s. Bij maatwerkontwerpen maken we daarbij vaak intensief gebruik van blockpatronen, blockstijlen en blockvariaties.

Bij het registreren van een block style kun je een style_handle meegeven. Tijdens het ontwikkelen van een maatwerkplugin viel het me eerder dit jaar (in maart) al op dat de bijbehorende stylesheet niet automatisch werd ingeladen. Destijds heb ik dat opgelost door de stijl handmatig te laden in een block render callback, waarbij ik controleerde of de custom style actief was. Onlangs liep ik bij het uitwerken van een campagnesite opnieuw tegen hetzelfde probleem aan. Ik ben de documentatie nog eens gaan nalezen en heb gezocht naar gerelateerde GitHub-issues. Al snel vond ik WordPress/Gutenberg issue #27244, waarin een gebruiker aangaf dat hij het probleem ook had ontdekt via de officiële documentatiepagina: https://developer.wordpress.org/themes/features/block-style-variations/.

Op die pagina staat inmiddels ook een duidelijke waarschuwing:

style_handle currently has a bug where it only enqueues the stylesheet in the editor but not on the front end. Until that linked ticket is addressed, its use is not recommended.

Block Style Variations – Theme Handbook | Developer.WordPress.org

Dat had ik eerder niet gezien. Ik ging er eigenlijk vanuit dat style_handle de aanbevolen en nette manier was om block-CSS aan te bieden, maar dat blijkt dus niet (meer) het geval te zijn. In de laatste reactie binnen het GitHub-issue wordt zelfs aangegeven dat de optie nooit echt goed gewerkt heeft en dat verwijderen misschien overwogen moet worden. Misschien is het gebruik van een inline_style voorlopig dus nog wel de meest betrouwbare aanpak.

<?php

\add_action(
	'init',
	function() {
		$url = \get_block_asset_url( __DIR__ . '/images/beige-cutout-1.svg' );

		\register_block_style(
			'core/group',
			[
				'name'         => 'custom-beige-cutout-1',
				'label'        => __( 'Beige cutout 1', 'custom' ),
				'inline_style' => <<<END
					.wp-block-group.is-style-custom-beige-cutout-1 {
						background-image: url("$url");
						background-repeat: no-repeat;
						position: calc( 100% + ( ( 1920px - 100vw ) * 0.2 ) ) top;
					}
					END,
			]
		);
	}
);

https://core.trac.wordpress.org/ticket/55184

Categorieën
WordPress

WordPress 6.7 en Twenty Twenty-Five

WordPress 6.7 staat gepland voor lancering op dinsdag 12 november 2024 en wordt de derde grote WordPress-update van dit jaar. De volledige ontwikkelingscyclus van WordPress 6.7 is te volgen via: https://make.wordpress.org/core/6-7/. Deze release introduceert naar verwachting ook het nieuwe standaardthema “Twenty Twenty-Five”, aangekondigd op 15 augustus 2024 in het bericht “Introducing Twenty Twenty-Five”. Bij Pronamic zijn we inmiddels bezig met het testen van onze plugins voor compatibiliteit met WordPress 6.7. De belangrijkste nieuwe functies en wijzigingen zijn beschreven in de WordPress 6.7 ‘field guide’. Vooral de verbeteringen in de Block Bindings en HTML API zijn veelbelovend, en een nieuw standaardthema is altijd interessant. Een demo van “Twenty Twenty-Five” is beschikbaar op https://2025.wordpress.net/.

Categorieën
E-commerce Gravity Forms iDEAL WooCommerce WordPress

Hoe kan ik Mollie koppelen aan WordPress of WooCommerce?

Het koppelen van Mollie aan WordPress of WooCommerce is goed mogelijk en er zijn verschillende oplossingen beschikbaar. Welke optie het beste is, hangt af van verschillende factoren. Wil je Mollie aan WordPress of WooCommerce koppelen? Hier vind je alle benodigde informatie.

Categorieën
PHP WordPress

Namespace in WordPress filter/action hooks

In februari stuitte ik op een bericht van Tanner Record waarin hij het gebruik van slashes in WordPress filter- en action-hooks voorstelde. Hij suggereert bijvoorbeeld de volgende conventie te volgen:

apply_filters( '{prefix}/{plugin}/{hook-name}', $data );

Gebruik in populaire WordPress plugins

Ik was een vergelijkbare notatie al wel tegen gekomen in populaire plugins zoals “Query Monitor” en “Advanced Custom Fields”:

Query Monitor

// Start the 'foo' timer:
do_action( 'qm/start', 'foo' );

// Run some code
my_potentially_slow_function();

// Stop the 'foo' timer:
do_action( 'qm/stop', 'foo' );

https://querymonitor.com/wordpress-debugging/profiling-and-logging

Advanced Custom Fields

add_action('acf/init', 'my_acf_init');

function my_acf_init() {
    // Get ACF version.
    $version = acf_get_setting('version');

    // Do something.  
}

Andere plugins

Mijn collega Reüel kwam nog met een reguliere expressie Github-zoekopdracht om het gebruik van deze notatie op te speuren in GitHub-repositories:

/do_action(\s['"]\w+\/\w+['"]\s(,.*?))/ language:PHP

Op basis hiervan heb ik al wel eens overwogen om een vergelijkbare notatie te introduceren in Pronamic-plugins. In de reacties op het bericht van Tanner worden echter ook een aantal nadelen genoemd.

Waarschuwing door “WordPress Coding Standards for PHP_CodeSniffer”

Bij het gebruik van de volgende notatie zal de “WordPress Coding Standards for PHP_CodeSniffer” bibliotheek een waarschuwing geven:

do_action( 'pronamic/plugin/init' );
Words in hook names should be separated using underscores. Expected: 'pronamic_plugin_init', but found: 'pronamic/plugin/init'.

De WordPress.NamingConventions.ValidHookName.UseUnderscores sniff waarschuwt hierover:

https://github.com/WordPress/WordPress-Coding-Standards/blob/29488feb64b723674fe463e691a4f83682c2dd5e/WordPress/Sniffs/NamingConventions/ValidHookNameSniff.php#L31

In de “Coding Standards Handbook” staat namelijk het volgende vermeld:

Use lowercase letters in variable, action/filter, and function names (never camelCase). Separate words via underscores.

https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/#naming-conventions

Nou is het prima mogelijk om af te wijken van de “WordPress Coding Standards”. Bij Pronamic hanteren we ook een eigen standaard, die op een paar punten afwijken van de “WordPress Coding Standards”: https://github.com/pronamic/wp-coding-standards.

Lastiger te selecteren en kopieren

Bij het dubbel klikken op een tekst zoals pronamic_plugin_init zal direct de hele tekst geselecteerd worden. Bij het dubbel klikken op de tekst pronamic/plugin/init zal alleen een deel tussen de slashes geselecteerd worden. Dit maakt het dat ik voor nu nog de pronamic_plugin_init notatie zal aanhouden.

Categorieën
WordPress

Website vertalen, meer verkoop?

Een website in meerdere talen: een uitdaging voor websitebouwers en klanten. De verleiding van een meertalige website is groot. Klanten hopen op een eenvoudige manier hun doelgroep in verschillende landen te kunnen bedienen. Maar is het opzetten van een meertalige website wel zo eenvoudig? Technisch gezien zijn er verschillende oplossingen beschikbaar. Plugins zoals WPML, MultilingualPress, TranslatePress, GTranslate, Polylang, etc. beloven een eenvoudige vertaling van je website. Maar schijn bedriegt. In de praktijk blijken deze plugins vaak wel complex of te buggy te zijn. Bij Pronamic zetten we een meertalige WordPress website vaak op met behulp van een WordPress multisite. Deze constructie biedt meer flexibiliteit en controle, en is minder gevoelig voor technische problemen. Toch is een WordPress multisite niet voor elke klant de juiste oplossing. Bepaalde klanten willen namelijk zo weinig mogelijk werk hebben van de vertalingen. Er lijkt wat dat betreft soms ook wat te makkelijk gedacht te worden over het opzetten van een website in meerdere talen. Zo zette het volgende bericht van Mark Zahra op X me ook aan het nadenken:

Who here has added translations to their digital product website and seen a resultant increase in sales? 🧐

Mark Zahra / RebelCode

Helaas werd er niet heel veel op gereageerd, maar Rogier Lankhorst van Really Simple Plugins (o.a. de maker van de Complianz GDPR/CCPA plugin) liet het volgende weten:

We tried it once on Complianz, with German, as a lot of customers are from Germany. It didn’t increase sales, but cost a lot of work to keep up to date. We dropped it after a while.

Rogier Lankhorst / Really Simple Plugins

Rogier noemt in een vervolgreactie ook dat automatische (slechte) vertalingen er ook voor kunnen zorgen dat je vertrouwen verliest. Nou ben ik zelf niet heel fanatiek bezig marketingwerkzaamheden, maar zie ik wel ook steeds vaker de term E-E-A-T (Experience, Expertise, Authoritativeness, and Trust) voor bij komen. Op basis daarvan kun je je misschien wel afvragen hoe slim het is om je website (geautomatiseerd) in meerdere talen aan te bieden. Kan een (automatische) vertaalde website in het Duits er voor zorgen dat je vertrouwen verliest waardoor ook je Nederlandse en/of Engelse website minder goed gaat scoren? En zorgt zo’n Duitse website wel daadwerkelijk voor meer verkoop? Of kun je met een een goede Engelse website hetzelfde resultaat behalen?

Categorieën
E-commerce WooCommerce WordPress

WooCommerce: meer betalen en meer issues

De ontwikkelingen binnen de WooCommerce webwinkel plugin gaan razendsnel. Er wordt o.a. hard gewerkt aan betere ondersteuning voor de WordPress “Full Site Editing” (FSE) functionaliteiten en de blok-editor. Op 9 januari werd WooCommerce versie 8.5.0 gelanceerd en op 15 februari werd versie 8.6.0 alweer uitgebracht. En de 8.7.0 release kan er ook op elk moment aankomen. Hartstikke mooi natuurlijk dat de ontwikkelingen zo snel gaan, maar het gaat ook wel gepaard met de nodige problemen. Binnen de “WordPress Nederland” workspace op Slack was daar dan ook al een kleine discussie over:

Hey, de 8.x releases van WooCommerce verliepen -op z’n zachts gezegd- niet zo denderend. Naar mijn mening ligt het tempo met de maandelijkse update te hoog. Maar ik ben benieuwd naar jullie mening. Ik heb een open vraag gesteld in het core-channel van WooCommerce Slack, dus benieuwd naar andere meningen. Deel ze gerust daar. Merci!

Dave Loodts – https://wpnl.slack.com/archives/C016TSB5GV9/p1708338050376959

Gelukkig zijn de Woo-ontwikkelaars wel bezig om documentatie en changelogs e.d. verder te verbeteren. Maar grotere webwinkels kan het ook wel veel tijd en geld kosten om mee te gaan in alle ontwikkelingen. Daarnaast lijkt Automattic met de rebranding van WooCommerce naar Woo ook de prijzen van verschillende plugins flink verhoogd te hebben. Op X gaf Ryan Waterbury hierover bijvoorbeeld het volgende aan:

In eerste instantie lijkt de gratis webwinkel plugin WooCommerce een voordelige keuze, maar in de praktijk zie je toch ook wel snel dat er allerlei betaalde plugins en diensten nodig zijn om een succesvolle webwinkel te kunnen draaien. Als je bijvoorbeeld de “Woo Subscriptions” plugin gebruikt dan komt de “AutomateWoo” plugin vaak ook wel van pas.

En zo kan het qua licenties voor plugins al snel optellen tot een aanzienlijk maand/jaarbedrag. Voor degenen die voor de keuze staan tussen bijvoorbeeld WooCommerce en Shopify kan dat wel iets zijn om rekening mee te houden.

Categorieën
PHP WordPress

Output buffering in WordPress

Het is alweer een paar weken geleden dat ik een bericht van Tanner Record op X voorbij zag komen op mijn tijdlijn over het gebruik van ‘output buffering’ in WordPress plugins:

Vergelijkbare constructies gebruiken we bij Pronamic ook regelmatig, maar ik herinnerde me ook een GitHub-issue binnen het “WordPress Coding Standards” voor PHP_CodeSniffer project: Add sniff to warn against using output buffering #1422. In dit issue stelt Juliette Reinders Folmer voor om een ‘sniff’ toe te voegen die gaat waarschuwen voor het gebruik van ‘output buffering’. Blijkbaar kunnen er ook problemen ontstaan bij het gebruik van ‘output buffering’ binnen WordPress. Zelf hebben we nog nooit met de genoemde problemen te maken gehad. Het is echter wel goed om te realiseren dat er dergelijke problemen kunnen ontstaan. In de reacties op het bericht van Tanner wordt ook voorgesteld om een PHP ’template engine’ zoals Blade of Twig te gebruiken. Een dergelijke ’template engine’ kan de nadelen van ‘output buffering’ wegnemen. Voor eenvoudige projecten zal ‘output buffering’ prima functioneren.

Categorieën
E-commerce iDEAL WooCommerce WordPress

Self-billing factuur van Mollie, Buckaroo, etc.

Omdat we bij Pronamic betaaloplossingen ontwikkelen voor payment providers zoals Mollie, Buckaroo, Pay.nl, etc. zijn we vaak partner van deze organisaties. In sommige gevallen krijgen we commissie voor succesvolle betalingen die via de Pronamic Pay plugin zijn opgestart. De payment providers betalen ons maandelijks of per kwartaal de opgebouwde commissie uit. Voor de boekhouding ontvangen we dan vaak een zogenaamde self-billing factuur. Waar voorheen nog wel eens creditnota’s werden verstuurd lijken de payment providers nu over te stappen naar self-billing facturen. Ik was tot vandaag niet heel bewust van dit concept. In dit bericht wat meer informatie over het self-billing principe.

Categorieën
Gravity Forms PHP WordPress

Koppeling Realworks Wonen API met WordPress en Gravity Forms

Voor een makelaar hebben we een koppeling gemaakt met de Realworks Wonen API en Gravity Forms. Woningzoekers kunnen op de website van de makelaar een Gravity Forms formulier invullen met contactgegevens en woonwensen. Deze gegevens worden vervolgens automatisch doorgezet naar Realworks. Daarmee hoeft de makelaar de formulier inzendingen niet meer handmatig in Realworks te zetten.