Blog

Stop met het herbouwen van elke WordPress-site

Een praktische, bezwaar-voor-bezwaar gids voor het standaardiseren van WordPress-builds met theme.json en block patterns—zonder elke clientsite in hetzelfde malletje te persen.

Samenvatting

De meeste bureaus bouwen elke WordPress-site vanuit een blanco thema, zelfs als een gedeelde basis weken van de planning zou schelen. Dit artikel stelt dat theme.json, block patterns en dynamische blocks je in staat stellen om de structurele laag te standaardiseren terwijl het eigen karakter van elke klant behouden blijft. Het gaat rechtstreeks in op de vijf bezwaren die teams ervan weerhouden om te veranderen: ‘we hebben verschillende klanten’, ‘custom blocks zijn duur’, ‘de editor is verwarrend’, ‘we verliezen onze hooks en filters’ en ‘FSE is niet productierijp’. Elk bezwaar krijgt een praktisch tegenargument en een concreet patroon dat je stapsgewijs kunt toepassen. De beloning is een herhaalbaar bouwproces dat maatwerk nog steeds op de juiste plek eert. Waarschuwing: er worden geen resetknoppen met één klik beloofd.

Hoeveel van je clientsites delen zelfs maar één regel code? Niet de copyrightregel — echte code. Als het antwoord 'nauwelijks' is, heb je de pijn al gevoeld: dezelfde hero-sectie die voor de negende keer opnieuw wordt opgebouwd, dezelfde team-grid-markup die van het ene project naar het volgende wordt gekopieerd, dezelfde preprocess-aanpassingen die in een half dozijn thema's worden vergeleken. Je hebt ook het verweer gehoord: 'Elke klant heeft andere behoeften.' Waar. Maar de conclusie die iedereen trekt — dat elke site een op maat gemaakte basis nodig heeft — is onjuist. Het WordPress-ecosysteem biedt nu een manier om de structurele onderdelen te standaardiseren zonder het ontwerp te standaardiseren: theme.json voor design tokens, block patterns voor terugkerende lay-outs, en dynamische blocks voor de handvol functies die echte server-side logica nodig hebben. Dit artikel gaat over de bezwaren die bureaus ervan weerhouden die stap te zetten, en wat daadwerkelijk werkt als je daar tegenin gaat.

Het bezwaar 'maar elke klant is anders'

Het onderliggende principe: standaardiseer de basis, niet het oppervlak. De reden om structuur in een gedeelde bibliotheek te bewaren, is juist om de visuele laag vrij te laten. Een theme.json-bestand is geen ontwerp — het is een set design tokens. Kleuren, witruimte en typografie zijn waarden, geen markup. Dat is de cruciale verschuiving: je kunt de markup delen terwijl een per-site theme.json de site er voor een ander merk totaal anders laat uitzien.

Neem twee klanten: een advocatenkantoor en een outdoor-winkel. Hun design-talen liggen mijlenver uit elkaar. Maar beide hebben een hero-sectie, een testimonial-grid en een call-to-action-band nodig. In plaats van de markup voor elk opnieuw op te bouwen, onderhoud je drie block patterns en laat je het theme.json van elke klant de kleuren, lettertypen en witruimte bepalen. De structuur blijft identiek; de design tokens veranderen het van het ene merk in het andere. Wanneer de winkel volgend voorjaar zijn kleurenpalet wijzigt, bewerk je één bestand op hun site — niet de markup in zes sjablonen.

In de praktijk betekent dit dat je team patterns als code maakt, ze registreert in een gedeelde plugin en theme.json op elke clientsite voor de verf laat zorgen. De klassennamen van het pattern worden je architectuur; de waarden worden de variabelen. Je kunt zelfs verder gaan en theme.json uitbreiden met aangepaste instellingen voor post types of plugin-output, hoewel je op een gegeven moment een configuratie-interface bouwt in plaats van een site — een valkuil die wordt besproken in onze blik op het uitbreiden van theme.json. Houd de gedeelde laag slank: die mag alleen bevatten wat bij meerdere klanten terugkeert. Op het moment dat je een instelling toevoegt 'voor het geval iemand het ooit wil', heb je een abstractie gecreëerd die meer kost om te onderhouden dan het oplevert.

Wanneer je een nieuwe klant opzet, zijn de eerste dertig minuten: de gedeelde patterns-plugin klonen, een nieuw theme.json maken met het palet en de lettertypeschaal van de klant, en hun logo en footer registreren. Dat is geen maatwerkbuild; het is een configuratietaak. Het resterende klantspecifieke werk zit in content, structuur en eventuele echt op maat gemaakte functies. Dit is het verschil tussen elk huis vanaf nul bouwen en een set geprefabriceerde plattegronden hebben die je kunt overschilderen en behangen. De vergelijking is losjes, maar het principe geldt: hoe meer je in theme.json-waarden stopt, hoe minder je aan markup hoeft te zitten.

Een van de eenvoudigste winsten is om te kijken hoe block patterns daadwerkelijk werken. Een pattern is gewoon een verzameling blokken met vooraf gedefinieerde content en styling. Je kunt elke blokconfiguratie opslaan als een pattern, waarna een klant het kan invoegen zonder te weten hoe het is opgebouwd. Dat betekent dat het pattern een 'ingangspunt' wordt voor niet-technische gebruikers. Wanneer je team het onderliggende pattern in code onderhoudt, krijgt de klant een consistente bibliotheek zonder ook maar één PHP-tag aan te raken.

Nu de kanttekening waar ik steeds op terugkom: niet overcentraliseren. Een theme.json met een instelling voor elke denkbare nuance is een onderhoudsmoeras. Gedeelde patterns mogen een sterke mening hebben, maar niet almachtig zijn. Als een klant een totaal andere lay-out nodig heeft — bijvoorbeeld een magazine-homepage met een groot featured-grid — past dat misschien niet in je standaard patternbibliotheek. Dat is oké. Standaardisatie betekent dat je wint op de 80% van projecten die op elkaar lijken, niet dat je elke site in dezelfde mal dwingt.

Het bezwaar 'custom blocks blazen het budget op'

Hier is een tegenprincipe dat saai klinkt maar geld bespaart: de meeste dingen waarvan je denkt dat ze een custom block nodig hebben, hebben dat niet. Core blocks plus een pattern kunnen de overgrote meerderheid van lay-outs afdekken. Het custom block is het laatste redmiddel, niet de eerste bedoeling.

Het klassieke voorbeeld is het team-grid. Als het eenmalig is, gebruik dan de core 'kolommen'- en 'groep'-blocks en laat de klant handmatig een avatar invoegen. Als drie klanten hetzelfde grid vragen met dezelfde 'sociale links onder de naam'-structuur, heb je nu een kandidaat voor een block pattern. Wanneer dat pattern nieuwe opties begint te verzamelen — hover-effecten, sorteren, sterrenbeoordelingen — wordt het pattern een onbeheersbare grabbelton, en dan is het tijd om een custom block te schrijven. De budgetvernietigende fout is om bij de eerste aanvraag meteen naar het custom block te grijpen.

Een verraderlijker scenario: de klant vraagt om een 'case study-carrousel'. De eerste neiging is om te denken: 'Ik heb een carrouselblock nodig.' Maar heeft hij echt een carrousel nodig? Misschien heeft hij een horizontaal scrollbare groep berichten nodig, wat core blocks kunnen afhandelen met een 'groep'-block en wat CSS. Of misschien heeft hij een dynamische lijst van recente casestudy's nodig, wat een dynamisch block is dat de CPT opvraagt. De vraag is niet 'welke functie wil de klant?' maar 'welke data is ervan afhankelijk?' Als de data statisch en door de klant bewerkbaar is, volstaat een pattern. Als de data uit een databasequery komt, is een dynamisch block gerechtvaardigd. Als de data in realtime vanuit een API moet worden bijgewerkt, heb je misschien te maken met een REST API-integratie in plaats daarvan — dat is weer een ander soort build.

Wanneer je wel een block bouwt, is block.json je vriend. Het is de single source of truth voor attributen, scripts en styles, waardoor het block draagbaar is tussen projecten. Het stelt je ook in staat om afhankelijkheden en vertalingen netjes te declareren, wat essentieel is wanneer je een bibliotheek over veel clientsites verspreidt. Voor content die afhankelijk is van live data, rendert een dynamisch block op de server, zodat je niet bij elke pageview een JavaScript-bundel hoeft te leveren. En als je block evolueert, kun je deprecaties netjes afhandelen zodat bestaande content niet breekt — onze gids voor block-deprecatie behandelt het exacte patroon.

Voordat je iets bouwt, kun je de beslissing door deze grid halen:

AanpakBest voorVermijd wanneer
Core blockEenmalige content, eenvoudige pagina'sDe lay-out wordt herhaald bij veel klanten en heeft rijke opties nodig
Block patternHerbruikbare lay-outs zonder logicaDe lay-out heeft conditionals, dynamische data of complexe interacties nodig
Custom blockHerhaald, data-gedreven of zeer specifiek gedragDe enige reden is een eenmalige sectie die met een class kan worden afgehandeld

Je wilt ook vanaf dag één nadenken over blocknamen. Een blocknaam is in wezen een contract met je content. Als je het wagent/team-grid noemt en het later hernoemt naar wagent/team-carousel, breek je bestaande content, tenzij je een deprecatiepad biedt. Kies generieke, op het doel gebaseerde namen die geen valse reclame worden naarmate het block evolueert. Dit is een variant van de naamgevingsdiscipline die we allemaal hebben geleerd van plugin-voorvoegsels, en het geldt net zo goed voor blocknamen.

De tegendraadse kijk hier is het nuttigste wat ik kan zeggen: het custom block dat je bouwt omdat een klant vroeg om 'gewoon één onderdeel', is bijna altijd een vergissing. Zeg vriendelijk nee, lever een core block met een class en bank de uren. Je krijgt meer respect van de klant — en een kleinere post op de onderhoudsbegroting.

Het bezwaar 'klanten breken de editor'

Dit bezwaar is voor de helft juist. De blokeditor zelf is niet het probleem; het probleem is dat je klanten te veel vrijheid geeft. theme.json kan vergrendelen wat bewerkbaar is: de sjablooneditor uitschakelen, toegestane blokken beperken en standaardstijlen instellen zodat een verkeerd geplaatste kolom minder schade aanricht. Sommige klanten zullen nog steeds dingen breken, maar je kunt een pagina in één klik terugzetten naar een opgeslagen pattern — iets wat de klassieke editor niet kon bieden.

Laat me een scenario schetsen. Een klant belt en zegt: 'Ik heb een sectie verplaatst en nu ziet de hele pagina er verkeerd uit.' Met een klassiek thema zou je inloggen, de CSS inspecteren en waarschijnlijk een uur bezig zijn om de lay-out te herstellen. Met een blokopstelling kun je de pagina openen, het contentgebied selecteren en het resetten naar het opgeslagen pattern. Het pattern is de basislijn; de wijzigingen van de klant zijn de overlay. Wanneer de overlay misgaat, verwijder je die. Dat is niet alleen een fijnere workflow; het is een fundamenteel meer vergevingsgezinde editor.

Nu de nuance: de meeste klanten willen helemaal niet veel bewerken. Ze willen tekst wijzigen, foto's vervangen en misschien een sectie herordenen. Het block pattern geeft je precies dat zonder de hele sitestructuur bloot te leggen. In die zin is de editor geen speeltje; het is een zoeker. Het is jouw taak om te kalibreren wat klanten kunnen zien. Dat betekent dat je de 'Templates'-instellingen kunt uitschakelen, de blokkeninserter kunt beperken tot een samengestelde lijst en zelfs lege patterns kunt vooraf invullen met placeholderwerk. De editor wordt een contentinvoerformulier in plaats van een webdesigncanvas.

Op het gebied van toegankelijkheid zijn het focusbeheer en de ondersteuning van het toetsenbord van de blokeditor over het algemeen beter dan de sjabloonvelden van een klassieke editor. Maar je moet er nog steeds voor zorgen dat patterns een goede koppenstructuur en toegankelijke namen hebben. Omdat het pattern over klanten wordt gedeeld, los je die problemen maar één keer op, wat weer een verborgen voordeel van standaardisatie is.

Het echt moeilijke deel is intern. Voor je team betekent het leren prototypen met blokken dat je de 'doe het in PHP'-gewoonte moet afleren. Dat is een echte kostenpost, maar het is een eenmalige kostenpost per persoon. Het is geen reden om de aanpak te vermijden; het is een reden om te beginnen met één patternbibliotheek en één vergevingsgezinde klant voordat je het overal uitrolt. Laat het refrein 'mijn klanten kunnen niet met blokken omgaan' niet verbergen dat je nog geen blokopstelling hebt geconfigureerd die hen halverwege tegemoetkomt.

Het bezwaar 'we hebben al hooks en filters'

Het principe hier is: je gooit hooks niet weg; je voegt een laag toe bovenop. Blokken zijn de presentatiegrens; hooks zijn nog steeds hoe je logica injecteert. De render-callback van een dynamisch block draait in PHP, wat betekent dat je dezelfde functies kunt aanroepen en dezelfde filters kunt toepassen die je al vertrouwt.

Stel je een plugin voor waarmee je met een filter een 'uitgelicht product'-veld aan elk bericht kunt toevoegen. Met een dynamisch block kun je een server-gerenderd block opnemen dat dat filter uitvoert en de uitvoer binnen de wrapper van het block afdrukt. De klant voegt het block in; de bestaande PHP-logica doet het zware werk. Er wordt niets weggegooid. Voor een nog concreter voorbeeld: een custom block dat recente projectberichten weergeeft. In de render-callback roep je get_posts() aan, loop je erdoor en pas je the_title() en the_permalink() toe — dezelfde template-tags die je al jaren gebruikt.

Dit is ook de plek om eerlijk te zijn over wat niet vertaalt. Sommige slimme oude thema's gebruiken template-parts met ingewikkelde conditionals die argumenten op basis van de paginacontext aannemen. Dat als een block herbouwen kan rommelig zijn. Maar je hoeft het niet in één keer te herbouwen. Het incrementele pad is om de PHP-logica te behouden, deze in een dynamisch block te wrappen en de markup naar het blocktemplate te verplaatsen. Vaak zul je merken dat je bestaande filterpatronen de nieuwe uitvoer aankunnen. En als de logica sterk gekoppeld is aan een sjabloonhiërarchie (bijv. 'toon dit anders op zoekresultaten'), kun je voor die specifieke weergaven nog steeds het klassieke sjabloon gebruiken, terwijl je voor gewone pagina's blokken gebruikt.

De REST API opent ook een andere deur: je kunt blokken bouwen die gegevens ophalen van andere WordPress-sites of services van derden. Een dynamisch block kan wp_remote_get() aanroepen om JSON op te halen en dit op de front-end te renderen. Dat is een krachtig patroon voor agency-builds waar klanten social feeds, productlijsten of interne gegevens willen tonen zonder een aparte integratie te beheren. Het nadeel is caching en foutafhandeling — als de externe API traag is, is je pagina traag. Houd op API gebaseerde blokken buiten kritieke boven-de-vouw content, of gebruik client-side rendering met een goede laadstatus.

Actions en filters draaien nog steeds rond opslaan en renderen; de hook-architectuur verdwijnt niet wanneer je blokken adopteert, het verhuist alleen naar een nieuwe context. Als je je begrip van waar actions en filters deze nieuwe blokwereld ontmoeten wilt opfrissen, is onze hooks-deep-dive een nuttig naslagwerk.

Het bezwaar 'FSE is niet productierijp'

Eerlijk is eerlijk, maar vraag wat 'risicovol' nu eigenlijk betekent. Full Site Editing heeft verschillende releases doorgemaakt en theme.json is een stabiel schema geworden. Het risico is niet dat de editor 'ineens kapotgaat' — het risico is dat de aangepaste code van je team misschien leunt op ouderwetse PHP-sjablonen die onhandig naast bloksjablonen bestaan. Ook gaan sommige plugins van derden er nog steeds vanuit dat je de klassieke editor of customizer gebruikt. Dat is een compatibiliteitsbeslissing, geen reden om het hele model overboord te gooien.

Een nuttige manier om ernaar te kijken: eenvoudige, herhaalbare sites met content in blokken zijn het minst risicovol. Klanten met een diep aangepast klassiek thema of propriëtaire plugins die hun eigen front-end renderen, zijn een hoog risico. Dat is een legitieme reden om voor die kleine niche bij klassieke thema's te blijven. De fout is om te doen alsof 'productierijp' één schakelaar is die aan of uit staat.

Voordat je een blokthema aan een klant voorstelt, doorloop je een snelle checklist:

  • Heeft de klant een sterk aangepast thema dat migratie vereist?
  • Ondersteunen de must-have plugins de Site Editor en de REST API?
  • Staat de hostingomgeving de bestandstoegang toe die het blokthema verwacht?
  • Heb je tijd vrijgemaakt voor patternontwerp, niet alleen voor blockregistratie?
  • Zal het team van de klant de editorwijzigingen tolereren, of hebben ze een vergrendeld sjabloon nodig?

Als een van de antwoorden nee is, pas dan de scope aan of gebruik een hybride aanpak. Dat is geen compromis; dat is technisch oordeelsvermogen. En als je een hybride bouwt, onthoud dan het verhaal over hooks en filters hierboven — je kunt oude logica nog steeds in dynamische blocks wrappen terwijl theme.json voor de globale uitstraling zorgt.

Versiebeheer van je theme.json is niet alleen een theoretische zorg. Ik heb meegemaakt dat de aangepaste blockbibliotheek van een bureau kapotging toen de klant WordPress bijwerkte en het style-bestand van het block, geregistreerd met wp_register_style(), onder een andere handle stond. De oplossing was eenvoudig, maar de paniek was echt. Een eenvoudig testproces — de update op een staging-kopie van de site uitvoeren, de belangrijkste pagina's doorklikken en dan pas uitrollen — lost de meeste van dit soort verrassingen op.

Het bezwaar dat je jezelf nog niet hebt gemaakt

Hier is het meta-bezwaar dat bureaus ervan weerhoudt te standaardiseren: 'Het is een grote verandering en er is geen tijd om het tijdens klantwerk te doen.' Dat is waar — dus doe het niet tijdens klantwerk. Kies een intern project of een kleine klant en bouw één patternbibliotheek. Gebruik theme.json als systeem voor design tokens. Voeg alleen een custom block toe als dat gerechtvaardigd is. Wrap de oude hooks waar ze helpen. Itereer.

Hier is een ruwe eerste 30 dagen:

  1. Audit je laatste vijf klantbuilds en zet de tien meest herhaalde lay-outonderdelen op een rij.
  2. Maak van die tien onderdelen block patterns, met een kleine set CSS-classes.
  3. Bouw een gedeelde plugin (of mu-plugin) die deze patterns registreert. Als je nog niet hebt nagedacht over pluginorganisatie hiervoor, scan dan eerst deze gids over het bouwen van robuuste plugins.
  4. Maak één theme.json dat past bij je baseline-ontwerp; voeg klantspecifieke waarden toe terwijl je projecten opzet.
  5. Kies een klein intern project of een vriendelijke klant en migreer het naar de stack.
  6. Documenteer één heldenverhaal van een klant die zijn homepage heeft bewerkt zonder jou te bellen.

Aan het einde van dat experiment heb je geen 'block-first'-badge om aan de muur te hangen. Je hebt een team dat een nieuwe clientsite kan opzetten vanuit een gedeelde basis zonder excuses over de planning. Je bent ook beter in staat om nee te zeggen tegen de vraag van de klant voor een 42e custom block — omdat je precies weet wat de core blocks kunnen, of omdat je kunt laten zien waarom een dynamisch block echt sneller zou zijn.

Zul je nog steeds maatwerksites bouwen? Ja. Sommige klanten zullen altijd een custom template, een op maat gemaakte pagina of een propriëtaire integratie nodig hebben die het niet waard is om in het gedeelde model te dwingen. Het doel is niet om maatwerk te elimineren — het is om het de uitzondering te maken in plaats van de standaard.

De herhaalbaarheid komt uit de saaie onderdelen: een solide theme.json-schema, een duidelijke patternbibliotheek en de discipline om de gedeelde laag slank te houden. Dat is niet de glimmende versie die je in webinars hoort. Het is de versie die de maandagochtend-blank-thema-blues verslaat.

Sources (5)