Claude Code kan meer dan bestanden lezen en foutmeldingen verklaren. In dit artikel bouwen we er een complete WordPress-site mee, van een lege installatie tot een site die online staat. Je leest per stap welke opdracht is gegeven, waarom die opdracht zo is opgeschreven en wat Claude er vervolgens mee deed. Ook lees je wat er niet in een keer goed ging, want dat hoort erbij en daar leer je het meeste van.
De site die we bouwen is een massagesalon voor gestreste katten. Dat is met opzet een verzonnen zaak, want bij een onderwerp als dit zie je meteen dat er niets uit een sjabloon komt rollen. Het eindresultaat staat op snorhaarenzen.goedgehost.nl en je kunt er zelf doorheen klikken.
Belangrijk vooraf. Dit artikel gaat ervan uit dat Claude Code al werkt en dat je verbinding met je hostingpakket in orde is. Hoe je dat instelt lees je in Claude Code gebruiken op je hostingpakket. Daar staat ook welke pakketten het aankunnen en waarom onze SSH-poort 55667 is. WordPress zelf is vooraf neergezet met Installatron, want dat regelt meteen de database en de automatische updates. Hoe dat gaat lees je in Scripts installeren met Installatron.
Kies eerst het juiste model. In Claude Code stel je in met welk model je werkt en dat maakt voor dit soort werk veel uit. Alles in dit artikel is gedaan met Opus, het zwaarste model. Een kleiner en sneller model als Haiku is prima voor een overzichtje of een korte vraag over een foutmelding. Bij het bouwen van een site loop je er tegen de grenzen aan, want zo'n model denkt minder ver vooruit, het controleert zijn eigen werk minder vaak en het overziet slechter wat een wijziging elders in je site doet. Zet het model op Opus voordat je begint.
Zo leest dit artikel
Elke stap heeft dezelfde opbouw en die opbouw is de kern van het verhaal. Eerst zie je de opdracht in een grijs blok. Dat is letterlijk wat er getypt is en verder niets. Daarna lees je waarom die opdracht zo is opgeschreven en wat er bij een vagere versie zou zijn misgegaan. Tot slot lees je wat Claude ermee deed, met de uitvoer erbij zoals die op het scherm verscheen.
Waar Claude in gewone taal antwoord gaf staat dat in een blok met een oranje streep ernaast. Zo zie je in een oogopslag welk deel jouw woorden zijn en welk deel van Claude komt.
Let bij het lezen op hoe eenvoudig de opdrachten zijn. Er staat nergens welke techniek gebruikt moet worden en dat is precies de bedoeling. Je schrijft op wat je wilt bereiken en Claude zoekt de weg ernaartoe.
Het uitgangspunt
Na de installatie stond er een kale WordPress met het standaardthema Twenty Twenty-Five, een voorbeeldbericht en een voorbeeldpagina. Precies wat je krijgt als je zelf op de knop drukt.
Het startpunt. Een verse installatie met het standaardthema en de standaardinhoud van WordPress.
Claude Code draaide op een Mac en niet op de server zelf. Dat is de manier die op GetLarge, GetPro en Premium Medium werkt. Claude bedenkt een commando, stuurt dat over SSH naar het hostingpakket en leest het antwoord terug. De rechten stonden de hele tijd op Manual, zodat elk commando eerst te zien was voordat het draaide. Dat is even wat meer klikken en het is het waard, want je ziet daardoor precies wat er met je bestanden gebeurt.
Stap 1: eerst kijken en nog niets veranderen
De verleiding is groot om meteen te vragen of Claude een site wil bouwen. Doe dat niet. Begin met een opdracht die niets verandert, want dan weet je zeker dat Claude het juiste pakket voor zich heeft voordat er iets wordt weggeschreven.
De prompt
Kijk via ssh gethost wat er op deze hosting staat. Welke versie van
WordPress draait er, welk thema staat aan en waar staan de mappen?
Verander nog niets.
Waarom zo geformuleerd. Het zinnetje aan het eind houdt de beslissing bij jou. Claude is erop gebouwd om dingen op te lossen, dus een opdracht die als een klus klinkt levert soms meteen een reparatie op van iets wat volgens hem niet klopt. Met dat zinnetje krijg je eerst een overzicht en bepaal je daarna zelf wat er moet gebeuren.
Wat Claude deed. Inloggen, in de domeinmap kijken en terugkomen met de versie, het actieve thema en de mappenstructuur. Onderweg viel iets op. WP-CLI, het opdrachtregelgereedschap van WordPress, staat op ons pakket wel klaar maar kan niet alles. De functie proc_open staat op gedeelde hosting uit om veiligheidsredenen en daar lopen een paar commando's op vast.
$ wp core version
7.1
$ wp rewrite structure "/%postname%/" --hard
Error: Cannot do 'launch option': The PHP functions `proc_open()` and/or
`proc_close()` are disabled.
Claude zocht daar zelf een weg omheen door wp rewrite flush te gebruiken zonder de optie die een extern proces start. Dat is precies het soort obstakel waar je bij gedeelde hosting tegenaan loopt en het is prettig dat je er niet zelf achter hoeft te komen.
Stap 2: de vormgeving en waarom het een childthema wordt
De tweede opdracht is de grote. Hier vertel je wat voor zaak het is, voor wie de site bedoeld is en welke toon hij moet hebben. Hoe concreter je bent over de sfeer, hoe minder je achteraf hoeft bij te sturen.
De prompt
Ik open een massagesalon voor gestreste katten en die heet Snorhaar & Zen.
Maak van deze site een rustige, warme website die daarbij past: zachte
kleuren, veel ruimte en geen felle knoppen. Zorg dat mijn aanpassingen
blijven staan als het thema een update krijgt.
Waarom zo geformuleerd. Let op de laatste zin. Je vraagt niet om een childthema, want dat woord hoef je niet te kennen. Je schrijft op wat je belangrijk vindt en Claude vertaalt dat naar de juiste oplossing. Een childthema was er waarschijnlijk ook zonder die zin gekomen, want dat is de gebruikelijke manier van werken en Claude weet dat. Het punt is dat je het dan aan het toeval overlaat. Door de eis op te schrijven weet je waar je achteraf op moet controleren en heb je iets om naar te wijzen als het toch anders loopt. Dat werkt voor elke eis die voor jou telt, zoals dat de site snel moet blijven of dat er niets aan je bestaande pagina's mag veranderen.
Wat Claude deed. Een childthema aanmaken met de naam Snorhaar & Zen, met een eigen stylesheet, een theme.json voor het kleurenpalet en eigen versies van de kop en de voettekst van de site. Het moederthema bleef ongemoeid. Ook zette Claude de sitetitel en de ondertitel goed, want Installatron had de site nog Mijn blog genoemd.
Stap 3: de openingstijden, waar Claude zijn eigen fout vond
Nu iets wat echt code vraagt. Een salon met een middagpauze is verrassend lastig, want je hebt twee losse blokken per dag en de vraag hoe lang het nog duurt kan drie kanten op.
De prompt
Zet op de site of we open zijn. We zijn doordeweeks open van negen tot
vijf met een pauze van een uur tot half drie, zaterdag van tien tot twee
en op zondag zijn we dicht. Ik wil er ook bij zien hoe lang we nog
open zijn.
Waarom zo geformuleerd. De tijden staan er precies in, want daar valt niets aan te raden. De laatste zin lijkt een detail en is het niet. Alleen open of dicht tonen is een kwestie van twee regels code. Zodra je erbij wilt weten hoe lang nog, moet er echt gerekend worden en komt de middagpauze in beeld.
Wat Claude deed. Een aparte plugin bouwen met een shortcode [salon_status] die je overal op de site kunt plakken. Een plugin en geen code in het thema, want dan blijft het werken als je later van thema wisselt. Daarna gebeurde het interessantste moment van de hele middag. Zonder dat erom gevraagd was schreef Claude er een testbestand bij dat de functie langs vijftien tijdstippen haalt. Dat testbestand ging meteen aan.
ma 08:30 Nu gesloten, morgen weer open om 9:00
ma 09:00 Nu open, nog 4 uur
ma 12:55 Nu open, nog 5 minuten
ma 13:00 Nu gesloten, morgen weer open om 9:00
ma 13:30 Nu gesloten, morgen weer open om 9:00
ma 14:30 Nu open, nog 2 uur en 30 minuten
za 09:00 Nu gesloten, maandag weer open om 9:00
Claude keek naar die uitvoer, stelde vast dat drie regels niet klopten en meldde uit zichzelf wat er aan de hand was.
De functie kijkt nooit naar de blokken die later vandaag nog komen, maar springt meteen naar de volgende dag. De middagpauze maakt het zichtbaar, alleen zit dezelfde fout ook gewoon 's ochtends voor openingstijd. Ik herschrijf het zo dat hij eerst de rest van vandaag afloopt.
Kijk goed naar wat daar staat. Om half twee is de salon in de pauze en gaat hij dezelfde middag om half drie weer open, maar er stond dat je tot morgen moest wachten. Dezelfde fout zat er om half negen 's ochtends en op zaterdagochtend. De middagpauze maakte het zichtbaar en zonder pauze was het waarschijnlijk maanden onopgemerkt gebleven.
Claude paste de functie aan en draaide dezelfde test opnieuw. Daarna klopten alle vijftien regels, inclusief het lastige geval van zaterdagmiddag twee uur, waar het antwoord maandag moet zijn omdat de zondag ertussen zit.
ma 08:30 Nu gesloten, vandaag weer open om 9:00
ma 13:30 Nu gesloten, vandaag weer open om 14:30
ma 17:00 Nu gesloten, morgen weer open om 9:00
za 09:00 Nu gesloten, vandaag weer open om 10:00
za 14:00 Nu gesloten, maandag weer open om 9:00
zo 12:00 Nu gesloten, morgen weer open om 9:00
Hier zit een les in die verder gaat dan deze site. Claude test uit zichzelf wanneer iets zich laat testen. Juist bij tijd, datums en bedragen is dat het verschil tussen werkend en bijna werkend. Gebeurt het een keer niet vanzelf, vraag er dan gewoon om. Een site die er goed uitziet kan er volstrekt naast zitten en dat merk je anders pas als een klant belt.
Stap 4: de behandelingen als eigen onderdeel van WordPress
De salon heeft tien behandelingen en elke behandeling hoort bij een andere vorm van kattenstress. Ze moeten los te bewerken zijn, met een prijs en een duur.
De prompt
We hebben tien behandelingen, elk voor een andere vorm van kattenstress,
met een prijs en een duur erbij. Ik wil ze los kunnen bewerken in
WordPress zoals ik ook een pagina bewerk. Op de site wil ik ze als
kaartjes onder elkaar zien.
Waarom zo geformuleerd. Er staat niet hoe het moet. Er staat wat je wilt bereiken en hoe je het straks zelf wilt kunnen onderhouden. Dat tweede is wat de oplossing bepaalt.
Wat Claude deed. Een eigen berichttype aanmaken, met een invulveldje voor de prijs en een voor de duur in het bewerkscherm van WordPress. Dat is de manier waarop een bouwer het ook zou doen. Het alternatief, tien losse pagina's met de prijs in de tekst, ziet er hetzelfde uit en werkt niet meer zodra je iets wilt sorteren of ergens anders wilt tonen.
Een behandeling met de prijs en de duur erboven. Die twee komen uit losse velden en staan niet in de tekst.
De teksten schreef Claude er zelf bij, in de droge toon die bij het onderwerp past. De Voederautomaat-sessie is voor katten van wie de automaat drie minuten te laat afging, inclusief herstel van het vertrouwen in de techniek. Bij Er Woont Hier Ook Een Hond zit drie kwartier in een kamer waar het naar helemaal niets ruikt. De Rode Stip eindigt altijd met een prooi die er wel is, van vilt.
Stap 5: de stresstest en de meldingen die zichzelf aanzetten
Tot nu toe stond alles vast op de pagina. Nu iets waar de bezoeker zelf iets doet en iets wat vanzelf verandert.
De prompt
Maak een testje van drie vragen waarmee een bezoeker ontdekt welke
behandeling bij zijn kat past. Er mag niets worden opgeslagen en er mag
geen mail uitgaan. Zet er ook een melding op de site die vanzelf
verandert: rond oud en nieuw iets over vuurwerk, in december over de
kerstboom en in de zomer een hitteadvies.
Waarom zo geformuleerd. De zin over opslaan en mail is er niet voor niets. Vraag je om een testje zonder die beperking, dan kan er zomaar een formulier bij komen dat antwoorden bewaart of een bevestiging stuurt. Op gedeelde hosting wil je dat niet zomaar, want je deelt de reputatie van de mailserver met andere klanten en je krijgt te maken met gegevens van bezoekers. Door de grens vooraf te noemen krijg je een testje dat met gewone links werkt en dat niets achterlaat.
Wat Claude deed. De drie vragen achter elkaar zetten, met de antwoorden in het adres van de pagina. Elke combinatie leidt naar een behandeling en de bezoeker kan altijd opnieuw beginnen.
Drie vragen en een advies. De antwoorden staan in het adres van de pagina, er wordt niets bewaard.
De seizoensmelding werkt op de klok van de server. Om te controleren of die klopt hoef je niet tot december te wachten en je moet zeker de datum van de live site niet verzetten. Claude testte het los, opnieuw uit zichzelf, met een bestandje dat de melding voor veertien verschillende datums opvraagt.
01-01 vuurwerk Vuurwerkspreekuur
02-14 verwarming De verwarming gaat weer aan
06-15 hitte Hitteadvies
08-28 hitte Hitteadvies
09-01 verwarming De verwarming gaat weer aan
12-01 kerst De boom staat er weer
12-26 kerst De boom staat er weer
12-27 vuurwerk Vuurwerkspreekuur
Op dezelfde manier kwam er een regel bij over de drukte in de wachtkamer. Die leidt het aantal katten af van het tijdstip, dus hij is voorspelbaar en er wordt niet gedaan alsof er echte bezoekers worden geteld. Tijdens de middagpauze staat er netjes dat de wachtkamer leeg is en het licht uit.
Stap 6: nakijken op de telefoon
De laatste stap is de saaiste en je slaat hem het snelst over. Doe dat niet, want meer dan de helft van je bezoekers kijkt op een telefoon.
De prompt
Loop de site na op een telefoonformaat en laat zien wat er niet klopt.
Waarom zo geformuleerd. Je vraagt om laten zien en niet om repareren. Zo houd je de beslissing bij jezelf en dat pakt hier goed uit.
Wat Claude deed. De eerste opname leek te laten zien dat de tekst rechts uit beeld liep en dat het menu was verdwenen. In plaats van meteen te repareren mat Claude eerst hoe breed de pagina werkelijk was.
Geen enkele overloop in een echte mobiele weergave. Het lag aan headless Chrome, niet aan de site.
De site was in orde en het gereedschap waarmee de opname was gemaakt hield zich niet aan het opgegeven formaat. Was er wel meteen gerepareerd, dan had er nu CSS in de site gestaan die een probleem oplost dat er niet is.
Op telefoonformaat schuiven de kaartjes onder elkaar en klapt het menu in.
Het resultaat
De site staat op snorhaarenzen.goedgehost.nl. Vijf pagina's, tien behandelingen, een childthema en een eigen plugin met vier onderdelen die uit de klok komen. Reacties staan uit, de permalinks zijn netjes en de automatische updates blijven aan.
De voorpagina. De regel met de openingstijden, het hitteadvies en de kaartjes komen alle drie uit de eigen plugin.
Dit is een basis en geen eindpunt
Wat je hierboven ziet is een sobere opzet die in een half uur is gebouwd. De vormgeving is rustig gehouden omdat de nadruk in dit artikel op de werkwijze ligt. Voor een echte zaak zou je hier niet stoppen. Dat hoeft ook niet, want doorbouwen gaat op precies dezelfde manier als hierboven. Je kijkt naar wat er staat, je zegt in gewone taal wat je anders wilt en je kijkt opnieuw.
Denk aan een grote foto boven aan de voorpagina, eigen beeld bij elke behandeling, een andere indeling met de kaartjes in twee kolommen of een galerij van de salon. Je kunt vragen om filters op de behandelingenpagina zodat bezoekers op prijs of op duur kunnen sorteren, om een blog met verhalen uit de praktijk, om een pagina met veelgestelde vragen of om een tweede taal. Vraag gerust om drie voorstellen voor een kleurenpalet en kies er daarna een uit. Bij vormgeving werkt het bijna altijd beter om in kleine stappen bij te sturen dan om alles in een keer te willen.
Twee dingen blijven daarbij hetzelfde. Wil je iets waarbij bezoekers gegevens achterlaten of waarbij er mail wordt verstuurd, kijk dan eerst wat dat betekent voor je pakket en voor de privacy van je bezoekers. En blijf na elke ronde zelf naar de site kijken, ook op je telefoon.
Wat het kostte
Het bouwen duurde ruim een half uur nadat WordPress eenmaal draaide. Daar zaten zes opdrachten in zoals je ze hierboven leest, plus een paar kortere berichten om bij te sturen, te controleren en op te ruimen. Die kortere berichten zijn het echte werk. Je vraagt om iets, je kijkt naar het resultaat, je zegt wat er niet klopt en je gaat verder.
Reken op meer tijd als je zelf de teksten aanlevert of als je een bestaande site aanpast in plaats van een verse installatie. Bij een site die al draait ben je een flink deel van je tijd kwijt aan uitzoeken wat er al staat en dat is precies waar de eerste stap uit dit artikel voor bedoeld is.
Wat er misging
Vier dingen gingen niet in een keer goed en ze zijn alle vier het vermelden waard.
De openingstijden klopten niet rond de middagpauze en dat is hierboven al beschreven. Het geval waarin je zelf zou moeten nadenken is ook precies het geval waar een taalmodel overheen leest.
De regel met de openingstijden plakte in de eerste versie tegen de linkerrand van de pagina in plaats van netjes in de tekstkolom. Claude zocht het na en kwam terug met de oorzaak.
De statusregel is inline-flex en dus inline, waardoor de automatische marges van WordPress niet pakken en hij tegen de rand van de volle breedte plakt.
De regel met de openingstijden staat tegen de rand en niet in de kolom. Zoiets zie je pas als je zelf kijkt.
Installatron had de site op het adres met www ervoor gezet en het korte adres stuurde daarheen door. Claude zette dat om en paste meteen de verwijzingen in de database aan. Met de hand is dat een klusje waar je een halfuur en een backup voor uittrekt.
Bij het overzetten van de bestanden vanaf de Mac gingen er verborgen bestandjes mee die macOS zelf maakt. Ze doen geen kwaad en ze horen niet op een server thuis. Claude ruimde ze op na een enkele opmerking dat ze er stonden.
Waar je op moet letten
Je werkt op gedeelde hosting en dat merk je. Een deel van WP-CLI werkt niet omdat er functies uitstaan. Dat is met reden zo. Claude zoekt daar zelf een weg omheen, alleen duurt het langer dan op een server die je helemaal voor jezelf hebt. De fair use policy geldt gewoon, dus laat Claude niet standaard je hele home-map doorzoeken.
Maak een backup voordat je Claude iets laat aanpassen aan een site die al draait. Bij WordPress zit je inhoud in de database en je vormgeving in de bestanden, dus je hebt beide nodig. Hoe je terugzet lees je in Een backup terugzetten met JetBackup. Voor deze demonstratie was dat niet nodig omdat er een verse installatie stond en er niets te verliezen viel.
Zet geen wachtwoorden, sleutels of logingegevens in je berichten. Wat Claude nodig heeft staat al in wp-config.php op de server en dat leest hij zelf wel. Voor het beheerscherm van WordPress heb je een gebruikersnaam en een wachtwoord nodig en die horen in je wachtwoordmanager en nergens anders.
Blijf zelf kijken wat er verandert. Claude schrijft echte bestanden naar je hostingpakket en gaat soms grondiger te werk dan je verwacht. De instelling Manual is daarvoor bedoeld en die staat er niet voor niets. Werk waar het kan eerst lokaal of in een aparte map en zet het daarna over, want dan is een misstap een kwestie van niet uploaden in plaats van terugdraaien.
Houd het aantal plugins laag en installeer alleen wat in de officiële map van WordPress staat. Voor deze site was een eigen plugin genoeg en die is met de site meegebouwd. Vraag Claude gerust om uit te leggen wat een plugin doet voordat je hem installeert, want dat is een vraag waar hij goed in is.
Kom je er niet uit, stuur ons dan een bericht met het commando dat je gebruikte en de melding die je kreeg. Over je code kunnen we niet meedenken, over de verbinding en over wat je pakket aankan wel.