{"id":65163,"date":"2026-04-07T08:00:12","date_gmt":"2026-04-07T06:00:12","guid":{"rendered":"https:\/\/kinsta.com\/nl\/?p=65163&#038;preview=true&#038;preview_id=65163"},"modified":"2026-04-07T09:01:03","modified_gmt":"2026-04-07T07:01:03","slug":"php-only-gutenberg-blokken","status":"publish","type":"post","link":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/","title":{"rendered":"Zo bouw je PHP-only Gutenberg blokken"},"content":{"rendered":"<div class=\"flex flex-col text-sm pb-25\">\n<section class=\"text-token-text-primary w-full focus:outline-none [--shadow-height:45px] has-data-writing-block:pointer-events-none has-data-writing-block:-mt-(--shadow-height) has-data-writing-block:pt-(--shadow-height) [&#038;:has([data-writing-block])&gt;*]:pointer-events-auto scroll-mt-[calc(var(--header-height)+min(200px,max(70px,20svh)))]\" dir=\"auto\" data-turn-id=\"request-WEB:efab47d4-3e40-4d17-90d8-bef3d9b43dde-39\" data-testid=\"conversation-turn-14\" data-scroll-anchor=\"true\" data-turn=\"assistant\">\n<div class=\"text-base my-auto mx-auto pb-10 [--thread-content-margin:var(--thread-content-margin-xs,calc(var(--spacing)*4))] @w-sm\/main:[--thread-content-margin:var(--thread-content-margin-sm,calc(var(--spacing)*6))] @w-lg\/main:[--thread-content-margin:var(--thread-content-margin-lg,calc(var(--spacing)*16))] px-(--thread-content-margin)\">\n<div class=\"[--thread-content-max-width:40rem] @w-lg\/main:[--thread-content-max-width:48rem] mx-auto max-w-(--thread-content-max-width) flex-1 group\/turn-messages focus-visible:outline-hidden relative flex w-full min-w-0 flex-col agent-turn\">\n<div class=\"flex max-w-full flex-col gap-4 grow\">\n<div class=\"min-h-8 text-message relative flex w-full flex-col items-end gap-2 text-start break-words whitespace-normal outline-none keyboard-focused:focus-ring [.text-message+&#038;]:mt-1\" dir=\"auto\" data-message-author-role=\"assistant\" data-message-id=\"3cf6f82d-9427-497f-b4bb-63d3f8b95194\" data-message-model-slug=\"gpt-5-3\" data-turn-start-message=\"true\">\n<div class=\"flex w-full flex-col gap-1 empty:hidden\">\n<div class=\"markdown prose dark:prose-invert w-full wrap-break-word dark markdown-new-styling\">\n<p data-start=\"0\" data-end=\"169\" data-is-last-node data-is-only-node>Jarenlang vereiste het ontwikkelen van Gutenberg-blokken een diepgaand begrip van technologie\u00ebn zoals React en Node.js, plus complexe buildprocessen en JavaScript tools.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"z-0 flex min-h-[46px] justify-start\"><\/div>\n<div class=\"mt-3 w-full empty:hidden\">\n<div class=\"text-center\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n<\/div>\n<p>WordPress ontwikkelt zich echter door, en je kunt Gutenberg-blokken nu volledig in PHP bouwen en beheren.<\/p>\n<p>Dit is vooral gunstig voor ontwikkelaars die liever React en server-side JavaScript (JS) ontwikkeling vermijden. Het verlaagt de leercurve, stroomlijnt de ervaring van de ontwikkelaar en maakt hogere prestaties mogelijk door onnodige front-end script overhead te verwijderen.<\/p>\n<p>In de volgende secties ontdek je hoe je deze nieuwe features gebruikt om PHP-only Gutenberg blokken te bouwen &#8211; en hoe je daarmee slankere, snellere en beter te onderhouden WordPress websites maakt.<\/p>\n<div class=\"flex flex-col text-sm pb-25\">\n<section class=\"text-token-text-primary w-full focus:outline-none [--shadow-height:45px] has-data-writing-block:pointer-events-none has-data-writing-block:-mt-(--shadow-height) has-data-writing-block:pt-(--shadow-height) [&#038;:has([data-writing-block])&gt;*]:pointer-events-auto scroll-mt-[calc(var(--header-height)+min(200px,max(70px,20svh)))]\" dir=\"auto\" data-turn-id=\"request-WEB:efab47d4-3e40-4d17-90d8-bef3d9b43dde-42\" data-testid=\"conversation-turn-20\" data-scroll-anchor=\"true\" data-turn=\"assistant\">\n<div class=\"text-base my-auto mx-auto pb-10 [--thread-content-margin:var(--thread-content-margin-xs,calc(var(--spacing)*4))] @w-sm\/main:[--thread-content-margin:var(--thread-content-margin-sm,calc(var(--spacing)*6))] @w-lg\/main:[--thread-content-margin:var(--thread-content-margin-lg,calc(var(--spacing)*16))] px-(--thread-content-margin)\">\n<div class=\"[--thread-content-max-width:40rem] @w-lg\/main:[--thread-content-max-width:48rem] mx-auto max-w-(--thread-content-max-width) flex-1 group\/turn-messages focus-visible:outline-hidden relative flex w-full min-w-0 flex-col agent-turn\">\n<div class=\"flex max-w-full flex-col gap-4 grow\">\n<div class=\"min-h-8 text-message relative flex w-full flex-col items-end gap-2 text-start break-words whitespace-normal outline-none keyboard-focused:focus-ring [.text-message+&#038;]:mt-1\" dir=\"auto\" data-message-author-role=\"assistant\" data-message-id=\"c0be0676-433c-465c-af10-059dd74f566f\" data-message-model-slug=\"gpt-5-3\" data-turn-start-message=\"true\">\n<div class=\"flex w-full flex-col gap-1 empty:hidden\">\n<div class=\"markdown prose dark:prose-invert w-full wrap-break-word dark markdown-new-styling\">\n<p data-start=\"0\" data-end=\"37\" data-is-last-node data-is-only-node>Klinkt goed, toch? Tijd om aan de slag te gaan!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"z-0 flex min-h-[46px] justify-start\"><\/div>\n<div class=\"mt-3 w-full empty:hidden\">\n<div class=\"text-center\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n<\/div>\n<p><aside role=\"note\" class=\"wp-block-kinsta-notice is-style-important\">\n            <h3>Important<\/h3>\n        <p>Houd er rekening mee dat de PHP-only blokken in dit artikel zich momenteel in de experimentele fase bevinden en onderhevig kunnen zijn aan wijzigingen. <strong>Gebruik deze feature niet in productie!<\/strong><\/p>\n<\/aside>\n<br \/>\n<div><\/div><kinsta-auto-toc heading=\"Table of Contents\" list-style=\"arrow\" selector=\"h2\" count-number=\"-1\"><\/kinsta-auto-toc><\/p>\n<h2>Wat zijn PHP-only blokken en waarom zijn ze belangrijk?<\/h2>\n<p>Het maken van een Gutenberg blok vereiste traditioneel geavanceerde server-side JavaScript en React codeervaardigheden. Dit vormde een belemmering voor de adoptie van de Block Editor door oude WordPress ontwikkelaars die misschien niet over de benodigde <a href=\"https:\/\/kinsta.com\/blog\/what-is-react-js\/\">React<\/a> en <a href=\"https:\/\/kinsta.com\/nl\/blog\/wat-is-node-js\/\">Node.js<\/a> kennis beschikten.<\/p>\n<p>Daar komt nu verandering in. Vanaf <a href=\"https:\/\/make.wordpress.org\/core\/2025\/10\/08\/whats-new-in-gutenberg-21-8-08-october\/\" target=\"_blank\" rel=\"noopener noreferrer\">Gutenberg 21.8<\/a> kun je Gutenberg blokken registreren met niets anders dan <a href=\"https:\/\/kinsta.com\/nl\/blog\/php-benchmarks\/\">PHP<\/a>. Dit neemt de complexiteit weg van het opzetten van een Node.js-omgeving voor ontwikkelaars die niet met server-side JavaScript werken.<\/p>\n<p>Met alleen PHP-blokregistratie kun je blokken registreren en weergeven in zowel de editor als de front-end met dezelfde PHP-code. Dit maakt het voor sites met hybride thema\u2019s of traditionele PHP-functies en <a href=\"https:\/\/kinsta.com\/nl\/blog\/wordpress-shortcodes\/\">shortcodes<\/a> makkelijker om de Block Editor te gebruiken en te ontwikkelen.<\/p>\n<p>Voor degenen die meer willen weten, zijn hier de belangrijkste GitHub PR&#8217;s gewijd aan PHP-only blokken.<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/WordPress\/gutenberg\/pull\/71794\" target=\"_blank\" rel=\"noopener noreferrer\">Allow registering PHP-only block<\/a>: Deze PR implementeert automatische server-side blokregistratie en hernoemt de <code>auto_ssr<\/code> ondersteuning naar <code>auto_register<\/code>.<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/gutenberg\/pull\/73556\" target=\"_blank\" rel=\"noopener noreferrer\">PHP-only blocks: Pass all metadata from PHP registration to the client<\/a>: PHP-only blokken met <code>auto_register<\/code> ondersteuning geven nu alle metadata van de PHP-registratie door aan de client.<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/gutenberg\/pull\/74102\">PHP-only blocks: Generate inspector controls from attributes<\/a>: Deze PR introduceert het automatisch genereren van de UI (Inspector Controls) op basis van de attributen die op de server zijn gedeclareerd.<\/li>\n<\/ul>\n<h2>Zo bouw je je eerste PHP-only Gutenberg-blok<\/h2>\n<p>Wanneer een blok alleen aan de kant van de server wordt geregistreerd &#8211; zonder JS-bestanden &#8211; en de nieuwe <code>auto_register<\/code> support flag is ingesteld op <code>true<\/code>, gebruikt de editor automatisch de <code>ServerSideRender<\/code> component om het blok aan de kant van de client te registreren en de preview van het blok weer te geven. In wezen wordt de inhoud van het blok nu direct gegenereerd vanuit de PHP-code in zowel de editor als de front-end.<\/p>\n<aside role=\"note\" class=\"wp-block-kinsta-notice is-style-important\">\n            <h3>Important<\/h3>\n        <p>De voorbeelden in dit artikel werken alleen als je <a href=\"https:\/\/make.wordpress.org\/core\/2025\/12\/17\/gutenberg-22-3-december-17\/\" target=\"_blank\" rel=\"noopener noreferrer\">Gutenberg 22.3<\/a>+ hebt ge\u00efnstalleerd op je ontwikkelwebsite.<\/p>\n<\/aside>\n\n<p>Ter illustratie is hier een eenvoudig PHP-voorbeeld dat een blok registreert met behulp van de PHP-only methode.<\/p>\n<pre><code class=\"language-php\">\/**\n * Render callback (frontend and editor)\n *\/\nfunction my_php_only_block_render( $attributes ) {\n\treturn '&lt;div&gt;\n\t\t&lt;h3&gt;\ud83d\ude80 PHP-only Block&lt;\/h3&gt;\n\t\t&lt;p&gt;This block was created with only PHP!&lt;\/p&gt;\n\t&lt;\/div&gt;';\n}\n\n\/**\n * Register the block on the 'init' hook.\n *\/\nadd_action( 'init', function() {\n\tregister_block_type( 'my-plugin\/php-only-test-block', array(\n\t\t'title'           =&gt; 'My PHP-only Block',\n\t\t'icon'            =&gt; 'welcome-learn-more',\n\t\t'category'        =&gt; 'text',\n\t\t'render_callback' =&gt; 'my_php_only_block_render',\n\t\t'supports'        =&gt; array(\n\t\t\t\/\/ Automatically registers the block in the Editor JS (previously auto_ssr)\n\t\t\t'auto_register' =&gt; true, \n\t\t),\n\t) );\n});<\/code><\/pre>\n<p>Je kunt deze code uitproberen door hem te kopi\u00ebren en te plakken in het hoofdbestand van een custom plugin. Na het activeren van de plugin zou je het &#8220;My PHP-Only Block&#8221; moeten zien in de Block Inserter.<\/p>\n<figure id=\"attachment_206054\" aria-describedby=\"caption-attachment-206054\" style=\"width: 1644px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206054 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/basic-php-only-block.png\" alt=\"Een eenvoudig PHP-only blok\" width=\"1644\" height=\"656\"><figcaption id=\"caption-attachment-206054\" class=\"wp-caption-text\">Een eenvoudig PHP-only blok<\/figcaption><\/figure>\n<p>De <a href=\"https:\/\/kinsta.com\/nl\/blog\/dynamische-blokken\/#register-the-block-on-the-server\">functie <code>register_block_type<\/code><\/a> registreert een bloktype op de server. Het bevat nu <a href=\"https:\/\/github.com\/WordPress\/gutenberg\/pull\/73556\" target=\"_blank\" rel=\"noopener noreferrer\">de nieuwe ondersteuning <code>auto_register<\/code><\/a>, die Gutenberg instrueert om metadata van de PHP registratie door te geven.<\/p>\n<p>De functie accepteert twee argumenten:<\/p>\n<ul>\n<li>De naam van het bloktype, inclusief de namespace. In dit voorbeeld is de bloknaam <code>my-plugin\/php-only-test-block<\/code>.<\/li>\n<li>Een array van argumenten voor het bloktype. In de bovenstaande code stellen we <code>titel<\/code>, <code>pictogram<\/code>, <code>categorie<\/code>, <code>render_callback<\/code> en <code>supports<\/code> in. Nogmaals, voor PHP-only bloktypes moet de <code>supports<\/code> array <code>'auto_register' =&gt; true<\/code> bevatten.<\/li>\n<\/ul>\n<p>Naast het vereenvoudigen van het maken van custom bloktypes en het eenvoudig integreren in hybride thema&#8217;s, kunnen PHP-only blokken worden gebruikt als wrappers voor oude PHP functies en shortcodes. Bovendien opent het gebruik van PHP-only blokken de deur naar nieuwe mogelijkheden voor custom integraties en server-side functionaliteit.<\/p>\n<p>Volgens <a href=\"https:\/\/github.com\/WordPress\/gutenberg\/issues\/71792\">H\u00e9ctor Priethor<\/a>,<\/p>\n<blockquote><p>Een puur PHP registratiemodel zou de minimale vereisten voor het ontwikkelen van blokken vereenvoudigen, waardoor ze beschikbaar worden voor een breder ontwikkelaarspubliek en het ecosysteem van blokken verder zou kunnen groeien dan geavanceerd JavaScript gebruik.<\/p><\/blockquote>\n<h2>Attributen gebruiken om de UI voor blokinstellingen te bouwen<\/h2>\n<p><a href=\"https:\/\/github.com\/WordPress\/gutenberg\/pull\/74102\" target=\"_blank\" rel=\"noopener noreferrer\">PR 74102<\/a> maakt het mogelijk om automatisch inspector besturingselementen te genereren uit definities van blokattributen. Hierdoor kunnen gebruikers het uiterlijk en de functionaliteit van je PHP-only blokken configureren zoals elk ander Gutenberg blok dat via JavaScript is geregistreerd.<\/p>\n<p>Voorheen moest je handmatig een <code>edit.js<\/code> bestand aanmaken in React en verschillende instellingscontroles defini\u00ebren met behulp van React componenten.<\/p>\n<p>Nu leest Gutenberg de attribuutdefinities en genereert automatisch de bijbehorende invoervelden in de WordPress editor.<\/p>\n<p>Het systeem koppelt de gegevenstypen die zijn gedefinieerd in de <code>attributen<\/code> array aan <code>DataForm<\/code> velddefinities.<\/p>\n<ul>\n<li><code>'type' =&gt; 'string'<\/code> genereert een tekstveld.<\/li>\n<li><code>type' =&gt; 'number'<\/code> genereert een getalveld.<\/li>\n<li><code>'type' =&gt; 'integer'<\/code> genereert een integer veld.<\/li>\n<li><code>'type' =&gt; 'boolean'<\/code> genereert een selectievakje.<\/li>\n<li><code>'type' =&gt; 'string'<\/code> met <code>'enum' =&gt; array()<\/code> genereert een select veld.<\/li>\n<\/ul>\n<p>Je zult je realiseren dat je maar een paar besturingselementen kunt gebruiken. Als je specifieke besturingselementen nodig hebt, zoals <code>RichText<\/code>, <code>RangeControl<\/code> of <code>ToggleControl<\/code>, zul je toch moeten kiezen voor de JS\/React aanpak.<\/p>\n<p>Deze toevoeging heeft echter aanzienlijke voordelen. De toetredingsdrempels worden verder verlaagd en je hoeft geen React, Webpack of NPM te leren om custom blokken met eenvoudige bewerkbare opties te maken.<\/p>\n<p>In het volgende voorbeeld breiden we het voorbeeldblok uit dat in de vorige sectie is getoond door enkele attributen toe te voegen.<\/p>\n<pre><code class=\"language-php\">\/**\n * 1. Define the block's HTML output.\n *\/\nfunction my_php_only_block_render( $attributes ) {\n\t\/\/ Extract attributes\n\t$title   = esc_html( $attributes['blockTitle'] );\n\t$count   = intval( $attributes['itemCount'] );\n\t$enabled = $attributes['isEnabled']; \/\/ Boolean from the ToggleControl\n\t$size    = esc_attr( $attributes['displaySize'] );\n\t\n\t\/\/ Start building the output\n\t$output = sprintf( '&lt;div class=\"my-php-block\" style=\"font-size: %s; border: 1px solid #ccc; padding: 15px;\"&gt;', \n\t\t$size === 'large' ? '20px' : ($size === 'small' ? '12px' : '16px') \n\t);\n\t\n\t$output .= sprintf( '&lt;h3&gt;\ud83d\ude80 %s&lt;\/h3&gt;', $title );\n\t\n\t\/\/ If the toggle is ON, show the list. If OFF, show a fallback message.\n\tif ( $enabled ) {\n\t\t$output .= '&lt;ul&gt;';\n\t\tfor ( $i = 1; $i &lt;= $count; $i++ ) {\n\t\t\t$output .= sprintf( '&lt;li&gt;Item %d&lt;\/li&gt;', $i );\n\t\t}\n\t\t$output .= '&lt;\/ul&gt;';\n\t} else {\n\t\t$output .= '&lt;p&gt;&lt;em&gt;The list is currently disabled.&lt;\/em&gt;&lt;\/p&gt;';\n\t}\n\t\n\t$output .= '&lt;\/div&gt;';\n\treturn $output;\n}\n\n\/**\n * 2. Register the block on 'init'.\n *\/\nadd_action( 'init', function() {\n\tregister_block_type( 'my-plugin\/php-only-test-block', array(\n\t\t'title'           =&gt; 'My PHP-only Block',\n\t\t'icon'            =&gt; 'welcome-learn-more',\n\t\t'category'        =&gt; 'text',\n\t\t'render_callback' =&gt; 'my_php_only_block_render',\n\n\t\t\/\/ Attributes used to generate the Inspector UI\n\t\t'attributes'      =&gt; array(\n\t\t\t'blockTitle'  =&gt; array(\n\t\t\t\t'type'    =&gt; 'string',\n\t\t\t\t'default' =&gt; 'PHP-only Block',\n\t\t\t),\n\t\t\t'itemCount'   =&gt; array(\n\t\t\t\t'type'    =&gt; 'integer',\n\t\t\t\t'default' =&gt; 3,\n\t\t\t),\n\t\t\t'isEnabled'   =&gt; array(\n\t\t\t\t'type'    =&gt; 'boolean',\n\t\t\t\t'default' =&gt; true,\n\t\t\t),\n\t\t\t'displaySize' =&gt; array(\n\t\t\t\t'type'    =&gt; 'string',\n\t\t\t\t'enum'    =&gt; array( 'small', 'medium', 'large' ),\n\t\t\t\t'default' =&gt; 'medium',\n\t\t\t),\n\t\t),\n\n\t\t'supports'        =&gt; array(\n\t\t\t'auto_register' =&gt; true, \n\t\t),\n\t) );\n});<\/code><\/pre>\n<p>Een blik op deze code laat zien hoe eenvoudig het is om een custom blok met al zijn configuratie-instellingen te registreren met behulp van de nieuwe API. Attributen worden nu niet alleen gebruikt om door de gebruiker ingevoerde gegevens op te slaan, maar ook om het UI-schema te defini\u00ebren. De bovenstaande code doet het volgende:<\/p>\n<ul>\n<li>De functie <code>register_block_type<\/code> registreert het bloktype <code>my-plugin\/php-only-test-block<\/code>.<\/li>\n<li>Het tweede argument dat aan de functie wordt doorgegeven is een array die de volgende elementen bevat: <code>title<\/code>, <code>icon<\/code>, <code>category<\/code>, <code>render_callback<\/code>, <code>attributes<\/code> en <code>supports<\/code>.<\/li>\n<li>De <code>attributes<\/code> array bevat de attributen van het blok. In het bovenstaande voorbeeld bevat de array de elementen <code>blockTitle<\/code>, <code>itemCount<\/code>, <code>isEnabled<\/code> en <code>displaySize<\/code>.<\/li>\n<li><code>auto_register' =&gt; true<\/code> schakelt server-side automatische registratie in.<\/li>\n<\/ul>\n<p>Dit is wat de callback-functie <code>my_php_only_block_render<\/code> doet:<\/p>\n<ul>\n<li>Eerst haalt de functie de attribuutwaarden uit de <code>$attributes<\/code> array en wijst ze toe aan de variabelen <code>$title<\/code>, <code>$count<\/code>, <code>$enabled<\/code> en <code>$size<\/code>.<\/li>\n<li>Daarna wordt de inhoud van het blok gegenereerd.<\/li>\n<\/ul>\n<p>Hier zie je het resultaat op het scherm:<\/p>\n<figure id=\"attachment_206110\" aria-describedby=\"caption-attachment-206110\" style=\"width: 2074px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206110 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/php-only-block-settings.png\" alt=\"Een PHP-only blok met blokinstellingen\" width=\"2074\" height=\"1102\"><figcaption id=\"caption-attachment-206110\" class=\"wp-caption-text\">Een PHP-only blok met blokinstellingen<\/figcaption><\/figure>\n<h2>Een praktijkvoorbeeld van PHP-only blokken<\/h2>\n<p>Hoewel er veel scenario&#8217;s zijn waarbij JavaScript nog steeds nodig is, kun je al veel doen met PHP-only blokken, vooral als je ze gebruikt met block props.<\/p>\n<p>In het volgende voorbeeld gebruiken we de <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_block_wrapper_attributes\/\" target=\"_blank\" rel=\"noopener noreferrer\">functie <code>get_block_wrapper_attributes()<\/code><\/a>, die een reeks attributen genereert voor het huidige blok dat wordt weergegeven. Het blok krijgt automatisch de door de gebruiker ingestelde kleuren, randen en schaduwen en past de bijbehorende stijlen toe op de hoofdcontainer. Op deze manier is het blok aanpasbaar via de eigen tools van Gutenberg, net als een React-gebaseerd blok.<\/p>\n<p>Om te zien hoe het werkt, maak je een <code>smart-pricing-widget<\/code> map aan op je computer. Maak in deze map een <code>style.css<\/code> bestand met de volgende CSS code:<\/p>\n<pre><code class=\"language-css\">\/* style.css *\/\n.pricing-card {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\ttext-align: center;\n\tbox-sizing: border-box;\n}\n\n.pricing-card h3 {\n\tmargin: 0;\n\tfont-size: 1.5rem;\n}\n\n.pricing-card .price-value {\n\tfont-size: 3.5rem;\n\tfont-weight: 800;\n\tmargin: 15px 0;\n}\n\n.pricing-card ul {\n\tlist-style: none;\n\tpadding: 25px 0;\n\tmargin: 20px 0;\n\twidth: 100%;\n\tborder-top: 1px solid rgba(128,128,128,0.3);\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n\n.pricing-card li {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: 10px;\n}\n\n.pricing-card .cta-button {\n\tmargin-top: auto;\n\tpadding: 15px 25px;\n\tborder-radius: 8px;\n\ttext-decoration: none;\n\tfont-weight: bold;\n\ttransition: opacity 0.2s;\n}\n\n.pricing-card .cta-button:hover {\n\topacity: 0.8;\n}\n\n\/* Theme Variations *\/\n.pricing-card.theme-light { background-color: #ffffff; color: #000000; }\n.pricing-card.theme-light .cta-button { background-color: #21759b; color: #ffffff; }\n\n.pricing-card.theme-dark { background-color: #1a1a1a; color: #ffffff; }\n.pricing-card.theme-dark .cta-button { background-color: #ffffff; color: #1a1a1a; }\n\n.pricing-card.theme-blue { background-color: #21759b; color: #ffffff; }\n.pricing-card.theme-blue .cta-button { background-color: #000000; color: #ffffff; }\n\n\/* Utility Classes *\/\n.pricing-card .is-full-width {\n\twidth: 100%;\n\tdisplay: block;\n\talign-self: stretch;\n}<\/code><\/pre>\n<p>We geven geen verder commentaar op deze code omdat het een eenvoudige stylesheet is voor je widgetblok.<\/p>\n<p>Maak nu het hoofdbestand voor je plugin, noem het <code>smart-pricing-widget.php<\/code> en plak de volgende code:<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\/**\n * Plugin Name: Smart Pricing Widget\n * Plugin URI:  https:\/\/example.com\/\n * Description: PHP-only Pricing Table block\n * Version:     1.2.0\n * Author:      Your Name\n * Text Domain: smart-pricing-widget\n *\/\n\nif ( ! defined( 'ABSPATH' ) ) exit;\n\n\/**\n * Render callback\n *\/\nfunction render_smart_pricing_block( $attributes ) {\n\t$plan_name = esc_html( $attributes['planName'] );\n\t$price     = intval( $attributes['price'] );\n\t$theme     = $attributes['blockTheme'];\n\t$btn_text  = esc_html( $attributes['buttonText'] );\n\t$btn_size  = $attributes['buttonSize'];\n\n\t$features_raw = $attributes['featuresList'];\n\t$features_array = array_filter( array_map( 'trim', explode( ',', $features_raw ) ) );\n\n\t$wrapper_attributes = wp_kses_data( get_block_wrapper_attributes( array(\n\t\t'class' =&gt; \"pricing-card theme-{$theme}\",\n\t) ) );\n\n\t$output = sprintf( '&lt;div %s&gt;', $wrapper_attributes );\n\t$output .= sprintf( '&lt;h3&gt;%s&lt;\/h3&gt;', $plan_name );\n\t$output .= sprintf( '&lt;div class=\"price-value\"&gt;\u20ac%d&lt;\/div&gt;', $price );\n\n\tif ( ! empty( $features_array ) ) {\n\t\t$output .= '&lt;ul&gt;';\n\t\tforeach ( $features_array as $feature ) {\n\t\t\t$is_checked = strpos( $feature, '+' ) === 0;\n\t\t\t$clean_text = esc_html( ltrim( $feature, '+- ' ) );\n\t\t\t$icon       = $is_checked ? '\u2705' : '\u274c';\n\t\t\t$style      = $is_checked ? '' : 'style=\"opacity: 0.6;\"';\n\t\t\t\n\t\t\t$output .= sprintf( '&lt;li %s&gt;&lt;span&gt;%s&lt;\/span&gt; %s&lt;\/li&gt;', $style, $icon, $clean_text );\n\t\t}\n\t\t$output .= '&lt;\/ul&gt;';\n\t}\n\n\t$btn_class = 'cta-button' . ( $btn_size === 'full' ? ' is-full-width' : '' );\n\t$output .= sprintf( '&lt;a href=\"#\" class=\"%s\"&gt;%s&lt;\/a&gt;', esc_attr( $btn_class ), $btn_text );\n\t$output .= '&lt;\/div&gt;';\n\n\treturn $output;\n}\n\n\/**\n * Register Assets and Block\n *\/\nadd_action( 'init', function() {\n\t\/\/ 1. Register the CSS file\n\twp_register_style(\n\t\t'smart-pricing-style',\n\t\tplugins_url( 'style.css', __FILE__ ),\n\t\tarray(),\n\t\t'1.2.0'\n\t);\n\n\t\/\/ 2. Register the Block\n\tregister_block_type( 'tutorial\/smart-pricing', array(\n\t\t'api_version'     =&gt; 3,\n\t\t'title'           =&gt; 'Pricing Card',\n\t\t'icon'            =&gt; 'cart',\n\t\t'category'        =&gt; 'widgets',\n\t\t'render_callback' =&gt; 'render_smart_pricing_block',\n\t\t\/\/ Link the registered style handle here\n\t\t'style'           =&gt; 'smart-pricing-style',\n\t\t'attributes'      =&gt; array(\n\t\t\t'planName'     =&gt; array( 'type' =&gt; 'string', 'default' =&gt; 'Professional' ),\n\t\t\t'price'        =&gt; array( 'type' =&gt; 'integer', 'default' =&gt; 49 ),\n\t\t\t'buttonText'   =&gt; array( 'type' =&gt; 'string', 'default' =&gt; 'Choose Plan' ),\n\t\t\t'buttonSize'   =&gt; array( 'type' =&gt; 'string', 'enum' =&gt; array( 'auto', 'full' ), 'default' =&gt; 'auto' ),\n\t\t\t'blockTheme'   =&gt; array( 'type' =&gt; 'string', 'enum' =&gt; array( 'light', 'dark', 'blue' ), 'default' =&gt; 'light' ),\n\t\t\t'featuresList' =&gt; array( 'type' =&gt; 'string', 'default' =&gt; \"+ Support, + Updates, - Domain\" ),\n\t\t),\n\t\t'supports'        =&gt; array(\n\t\t\t'auto_register' =&gt; true,\n\t\t\t'color'         =&gt; array( 'background' =&gt; true, 'text' =&gt; true ),\n\t\t\t'spacing'       =&gt; array( 'margin' =&gt; true, 'padding' =&gt; true ),\n\t\t\t'typography'    =&gt; array( 'fontSize' =&gt; true ),\n\t\t\t'shadow'        =&gt; true,\n\t\t\t'__experimentalBorder' =&gt; array( 'color' =&gt; true, 'radius' =&gt; true, 'style' =&gt; true, 'width' =&gt; true ),\n\t\t\t'border'        =&gt; array( 'color' =&gt; true, 'radius' =&gt; true, 'style' =&gt; true, 'width' =&gt; true ),\n\t\t),\n\t) );\n});<\/code><\/pre>\n<p>Dit script bevat twee functies. De functie <code>register_block_type()<\/code> is de motor van je plugin. Dit zijn de belangrijkste elementen:<\/p>\n<ul>\n<li>Het eerste argument is de blok identifier, inclusief de namespace (<code>tutorial\/smart-pricing<\/code>).<\/li>\n<li>Het tweede argument is een array van argumenten. In de bovenstaande code hebben we de API versie, titel, pictogram, categorie, render callback, stijl, attributen en <a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/block-api\/block-supports\/\" target=\"_blank\" rel=\"noopener noreferrer\">ondersteuning<\/a> ingesteld.<\/li>\n<li>De attributen in de array genereren de besturingselementen die gebruikers zullen gebruiken om inhoud toe te voegen en het blok te configureren. Het <code>type<\/code> element specificeert het type besturingselement dat moet worden toegevoegd aan de blokinspector. In dit voorbeeld zijn dat tekstvelden (<code>'type' =&gt; 'string'<\/code>), een geheel getal (<code>'type' =&gt; 'integer'<\/code>) en een paar vervolgkeuzemenu&#8217;s (<code>'type' =&gt; 'string', 'enum' =&gt; array()<\/code>).<\/li>\n<li>De <code>supports<\/code> array items voegen eigenschappen toe die de blokstijl aanpasbaar maken. Zoals we al eerder zeiden, is de enige ondersteuning die nodig is in een blok dat alleen uit PHP bestaat <code>auto_register<\/code>, dat het automatisch genereren van UI voor custom attributen mogelijk maakt. De andere hierboven aangegeven ondersteuningen zijn kleur, spati\u00ebring, typografie, schaduw en rand.<\/li>\n<\/ul>\n<p>De callback functie <code>render_smart_pricing_block()<\/code> genereert de HTML van het blok. Hier volgt een gedetailleerde beschrijving van wat deze functie doet:<\/p>\n<ul>\n<li>Het extract en saniteert de blokattributen, voegt dan de CSS-code toe die het uiterlijk van het blok in de frontend en editor genereert.<\/li>\n<li>De kenmerken die in het blok moeten worden weergegeven (<code>$attributes['featuresList'];<\/code>) worden apart behandeld. Op dit moment is het niet mogelijk om geavanceerde besturingselementen toe te voegen aan de zijbalk met blokinstellingen. Om een lijst te maken, zoals een lijst met kenmerken, kun je alleen een eenvoudig tekstveld gebruiken. In dit voorbeeld moet je de productkenmerken handmatig invoeren, gescheiden door komma&#8217;s.<\/li>\n<li>De variabele <code>$wrapper_attributes<\/code> is een container voor de wrapperattributen die worden geleverd door de <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_block_wrapper_attributes\/\">functie <code>get_block_wrapper_attributes<\/code><\/a>. Deze functie voegt niet alleen de klassen toe die in de code zijn gespecificeerd (<code>pricing-card theme-{$theme}<\/code>), maar haalt automatisch alle stijlaanpassingen op die de gebruiker in de block inspector heeft ingesteld, inclusief kleuren, randen, opvulling, marge, schaduw, typografie en de standaard blokklassen (<code>wp-block-tutorial-smart-pricing<\/code>).<\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_kses_data\/\"><code>wp_kses_data<\/code><\/a> zorgt ervoor dat er geen kwaadaardige tags of scripts (XSS) in de string zitten.<\/li>\n<li>De rest van de code genereert de inhoud van het blok.<\/li>\n<\/ul>\n<p>Activeer de plugin en maak een nieuw bericht of pagina. Open de block inserter en scroll naar beneden naar de Widgets sectie. Hier zou je het blok &#8220;Pricing Card&#8221; moeten zien, herkenbaar aan het pictogram van een winkelwagentje.<\/p>\n<figure id=\"attachment_206128\" aria-describedby=\"caption-attachment-206128\" style=\"width: 2034px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206128 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/php-only-block-example.png\" alt=\"Een custom PHP-only blok in de Block Editor\" width=\"2034\" height=\"1322\"><figcaption id=\"caption-attachment-206128\" class=\"wp-caption-text\">Een custom PHP-only blok in de Block Editor<\/figcaption><\/figure>\n<p>De afbeelding hierboven toont het blok met het standaard lichte thema.<\/p>\n<p>In de afbeelding hieronder zie je de donkere versie van het blok en de instellingen die je in je plugin hebt opgegeven.<\/p>\n<figure id=\"attachment_206129\" aria-describedby=\"caption-attachment-206129\" style=\"width: 2188px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206129 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/php-only-dark-theme-block-settings.png\" alt=\"Het PHP-only blok met blokinstellingen\" width=\"2188\" height=\"1652\"><figcaption id=\"caption-attachment-206129\" class=\"wp-caption-text\">Het PHP-only blok met blokinstellingen<\/figcaption><\/figure>\n<p>De volgende afbeelding toont de stijlelementen die je hebt toegevoegd met de blok supports.<\/p>\n<figure id=\"attachment_206130\" aria-describedby=\"caption-attachment-206130\" style=\"width: 2104px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206130 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/php-only-customized-dark-theme.png\" alt=\"Het donkere thema van het PHP-only blok met custom kleuren\" width=\"2104\" height=\"1310\"><figcaption id=\"caption-attachment-206130\" class=\"wp-caption-text\">Het donkere thema van het PHP-only blok met custom kleuren<\/figcaption><\/figure>\n<p>Het is ook de moeite waard om op te merken dat stijlen die zijn toegevoegd door supports de stijlen van het blokkenthema overschrijven. Hierdoor kan het uiterlijk van het blok beter worden aangepast, zoals te zien is in de volgende afbeelding:<\/p>\n<figure id=\"attachment_206131\" aria-describedby=\"caption-attachment-206131\" style=\"width: 2406px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206131 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/customized-php-only-blocks.png\" alt=\"Een prijstabel voor 3 serviceniveaus met drie instanties van je PHP-only blok\" width=\"2406\" height=\"1362\"><figcaption id=\"caption-attachment-206131\" class=\"wp-caption-text\">Een prijstabel voor 3 serviceniveaus met drie instanties van je PHP-only blok<\/figcaption><\/figure>\n<h2>Oude shortcodes omzetten naar Gutenberg blokken met pure PHP<\/h2>\n<p>Een van de meest directe toepassingen van PHP blokken is als shortcode wrapper. Met Gutenberg kun je nog steeds shortcodes gebruiken in je content, maar je moet je shortcode handmatig invoegen in een Shortcode blok, wat niet de meest prettige ervaring is.<\/p>\n<p>Stel je hebt de volgende shortcode:<\/p>\n<pre><code class=\"language-php\">function my_custom_alert_shortcode( $atts ) {\n\t$options = shortcode_atts( array(\n\t\t'type'    =&gt; 'info',\n\t\t'message' =&gt; 'Default alert message',\n\t), $atts );\n\n\t$styles = array(\n\t\t'info'    =&gt; 'background: #d1ecf1; color: #0c5460; border-color: #bee5eb;',\n\t\t'warning' =&gt; 'background: #fff3cd; color: #856404; border-color: #ffeeba;',\n\t\t'error'   =&gt; 'background: #f8d7da; color: #721c24; border-color: #f5c6cb;'\n\t);\n\n\t$style = $styles[ $options['type'] ] ?? $styles['info'];\n\n\treturn sprintf(\n\t\t'&lt;div class=\"sc-alert-box\" style=\"%s padding: 20px; border: 1px solid; border-radius: 6px; margin: 10px 0;\"&gt;\n\t\t\t&lt;strong style=\"text-transform: uppercase;\"&gt;%s:&lt;\/strong&gt; %s\n\t\t&lt;\/div&gt;',\n\t\tesc_attr( $style ),\n\t\tesc_html( $options['type'] ),\n\t\tesc_html( $options['message'] )\n\t);\n}\nadd_shortcode( 'sc_alert', 'my_custom_alert_shortcode' );<\/code><\/pre>\n<p>Deze code genereert een eenvoudige box die je in je inhoud kunt invoegen met de volgende shortcode:<\/p>\n<pre><code class=\"language-text\">[sc_alert type=\"alert\" message=\"Hello\"]<\/code><\/pre>\n<p>In Gutenberg gebruik je een Shortcode blok om het vak in je inhoud in te voegen, zoals te zien is in de volgende afbeelding:<\/p>\n<figure id=\"attachment_206137\" aria-describedby=\"caption-attachment-206137\" style=\"width: 1304px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206137 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/shortcode-block.png\" alt=\"Een Shortcode blok\" width=\"1304\" height=\"272\"><figcaption id=\"caption-attachment-206137\" class=\"wp-caption-text\">Een Shortcode blok<\/figcaption><\/figure>\n<p>Het scenario verandert volledig met PHP-only blokken. Nu kun je je shortcode in een PHP-only Gutenberg-blok wrappen en het configureren via de UI-besturingselementen. Hier is de code die je aan je plugin moet toevoegen:<\/p>\n<pre><code class=\"language-php\">\/**\n * Rendering callback\n *\/\nfunction render_shortcode_alert_wrapper_block( $attributes ) {\n\n\t$type    = esc_attr( $attributes['alertType'] );\n\t$message = esc_attr( $attributes['alertMessage'] );\n\n\t$shortcode_string = sprintf( '[sc_alert type=\"%s\" message=\"%s\"]', $type, $message );\n\n\t$wrapper_attributes = wp_kses_data( get_block_wrapper_attributes( array(\n\t\t'class' =&gt; 'wp-block-shortcode-alert-wrapper',\n\t) ) );\n\n\treturn sprintf(\n\t\t'&lt;div %s&gt;%s&lt;\/div&gt;',\n\t\t$wrapper_attributes,\n\t\tdo_shortcode( $shortcode_string )\n\t);\n}\n\n\/**\n * Register the block type on the server\n *\/\nadd_action( 'init', function() {\n\tregister_block_type( 'tutorial\/alert-wrapper', array(\n\t\t'api_version'     =&gt; 3,\n\t\t'title'           =&gt; 'Alert (Shortcode wrapper)',\n\t\t'icon'            =&gt; 'feedback',\n\t\t'category'        =&gt; 'widgets',\n\t\t'render_callback' =&gt; 'render_shortcode_alert_wrapper_block',\n\t\t\n\t\t'attributes'      =&gt; array(\n\t\t\t'alertType' =&gt; array(\n\t\t\t\t'type'    =&gt; 'string',\n\t\t\t\t'enum'    =&gt; array( 'info', 'warning', 'error' ),\n\t\t\t\t'default' =&gt; 'info',\n\t\t\t),\n\t\t\t'alertMessage' =&gt; array(\n\t\t\t\t'type'    =&gt; 'string',\n\t\t\t\t'default' =&gt; 'Type your alert message here...',\n\t\t\t),\n\t\t),\n\n\t\t'supports'        =&gt; array(\n\t\t\t'auto_register' =&gt; true,\n\t\t\t'spacing'       =&gt; array( 'margin' =&gt; true, 'padding' =&gt; true ),\n\t\t\t'typography'    =&gt; array( 'fontSize' =&gt; true ),\n\t\t),\n\t) );\n});<\/code><\/pre>\n<p>De bovenstaande code is vergelijkbaar met de code in de vorige sectie. Wat hier verandert is de rendering callback.<\/p>\n<ul>\n<li><code>$shortcode_string<\/code> slaat de shortcode string op (<code>[sc_alert type=\"%s\" message=\"%s\"]<\/code>).<\/li>\n<li>De functie retourneert de HTML van de blokcontainer en de opgenomen shortcode (<code class=\"language-php\">do_shortcode( $shortcode_string )<\/code>).<\/li>\n<\/ul>\n<p>Open nu de block inserter en zoek het blok &#8220;Shortcode wrapper&#8221; tussen de widgets. Voeg het in je inhoud in en configureer het via de blokinstellingenbalk. Het blok zal identiek verschijnen in zowel de editor als de front-end.<\/p>\n<figure id=\"attachment_206135\" aria-describedby=\"caption-attachment-206135\" style=\"width: 2298px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-206135 size-full\" src=\"https:\/\/kinsta.com\/wp-content\/uploads\/2026\/02\/php-only-shortcode-example.png\" alt=\"Een voorbeeld van een shortcode gewrapt in een PHP-only blok\" width=\"2298\" height=\"912\"><figcaption id=\"caption-attachment-206135\" class=\"wp-caption-text\">Een voorbeeld van een shortcode gewrapt in een PHP-only blok<\/figcaption><\/figure>\n<h2>Hoe verandert de ontwikkeling van WordPress met PHP-only blokken?<\/h2>\n<p>Op dit moment bevinden pure PHP-blokken zich in een experimentele fase en hebben ze nog steeds beperkte mogelijkheden. Gutenberg biedt krachtigere features, zoals <a href=\"https:\/\/kinsta.com\/nl\/blog\/wordpress-blokpatronen\/\">blokpatronen<\/a> en <a href=\"https:\/\/kinsta.com\/nl\/blog\/stijl-blokvariaties-gutenberg\/\">blokvariaties<\/a>, die alle bewerkingsfuncties bieden van native Gutenberg blokken en custom blokken die zijn gebouwd in JavaScript. Toch zijn er scenario&#8217;s waarin PHP-blokken aanzienlijke mogelijkheden bieden.<\/p>\n<p>Ten eerste zouden PHP-only blokken voor een bredere toepassing van de Block Editor moeten zorgen, vooral onder WordPress ontwikkelaars die minder geori\u00ebnteerd zijn op server-side JavaScript ontwikkeling.<\/p>\n<p>Verder zijn het ideale wrappers voor custom functies en shortcodes, zoals het voorbeeld in dit artikel laat zien. Bovendien maken ze eenvoudige integratie met externe diensten mogelijk.<\/p>\n<p>En we kunnen ook redelijkerwijs toekomstige verbeteringen en functietoevoegingen, meer configuratiecontroles en integraties met bestaande Gutenberg tools verwachten.<\/p>\n<p>E\u00e9n ding is zeker: met alleen PHP-blokken is het bouwen van Gutenberg-blokken veel gemakkelijker geworden.<\/p>\n<p>Als WordPress ontwikkeling je werk is, dan biedt Kinsta de <a href=\"https:\/\/kinsta.com\/nl\/blog\/wordpress-bureau-tech-stack\/\">ontwikkelaarstools die je nodig hebt<\/a>, zodat je je kunt richten op WordPress ontwikkeling en geen complexe configuraties en vervelende onderhoudstaken meer nodig hebt: <a href=\"https:\/\/kinsta.com\/nl\/blog\/wordpress-op-afstand-ontwikkelen-kinsta-ssh\/\">SSH<\/a>, <a href=\"https:\/\/kinsta.com\/nl\/blog\/sftp-ssh-features\/\">SFTP<\/a>, <a href=\"https:\/\/kinsta.com\/nl\/blog\/ci-cd-pipeline-maken\/\">Git-integratie<\/a>, <a href=\"https:\/\/kinsta.com\/nl\/blog\/kinsta-automatische-updates\/\">automatische updates<\/a>, <a href=\"https:\/\/kinsta.com\/nl\/wordpress-hosting\/testomgevingen\/\">testomgevingen met \u00e9\u00e9n klik<\/a>, een ingebouwde <a href=\"https:\/\/kinsta.com\/nl\/devkinsta\/features\/\">lokale ontwikkeltool<\/a> en nog veel meer. Probeer het uit met <a href=\"https:\/\/kinsta.com\/nl\/eerste-maand-gratis\/\">je eerste gratis maand<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jarenlang vereiste het ontwikkelen van Gutenberg-blokken een diepgaand begrip van technologie\u00ebn zoals React en Node.js, plus complexe buildprocessen en JavaScript tools. WordPress ontwikkelt zich echter door, &#8230;<\/p>\n","protected":false},"author":36,"featured_media":65164,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_kinsta_gated_content":false,"_kinsta_gated_content_redirect":"","footnotes":""},"tags":[],"topic":[865,892],"class_list":["post-65163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","topic-php-functie","topic-wordpress-ontwikkeling"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v24.6 (Yoast SEO v24.6) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Zo bouw je PHP-only blokken in Gutenberg<\/title>\n<meta name=\"description\" content=\"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Zo bouw je PHP-only Gutenberg blokken\" \/>\n<meta property=\"og:description\" content=\"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/\" \/>\n<meta property=\"og:site_name\" content=\"Kinsta\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-04-07T06:00:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-07T07:01:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1470\" \/>\n\t<meta property=\"og:image:height\" content=\"735\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Carlo Daniele\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png\" \/>\n<meta name=\"twitter:creator\" content=\"@carlodaniele\" \/>\n<meta name=\"twitter:site\" content=\"@Kinsta_NL\" \/>\n<meta name=\"twitter:label1\" content=\"Geschreven door\" \/>\n\t<meta name=\"twitter:data1\" content=\"Carlo Daniele\" \/>\n\t<meta name=\"twitter:label2\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/\"},\"author\":{\"name\":\"Carlo Daniele\",\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63\"},\"headline\":\"Zo bouw je PHP-only Gutenberg blokken\",\"datePublished\":\"2026-04-07T06:00:12+00:00\",\"dateModified\":\"2026-04-07T07:01:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/\"},\"wordCount\":2159,\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#organization\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png\",\"inLanguage\":\"nl-NL\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/\",\"url\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/\",\"name\":\"Zo bouw je PHP-only blokken in Gutenberg\",\"isPartOf\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png\",\"datePublished\":\"2026-04-07T06:00:12+00:00\",\"dateModified\":\"2026-04-07T07:01:03+00:00\",\"description\":\"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.\",\"breadcrumb\":{\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage\",\"url\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png\",\"contentUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png\",\"width\":1470,\"height\":735},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/kinsta.com\/nl\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"WordPress ontwikkeling\",\"item\":\"https:\/\/kinsta.com\/nl\/onderwerpen\/wordpress-ontwikkeling\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Zo bouw je PHP-only Gutenberg blokken\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kinsta.com\/nl\/#website\",\"url\":\"https:\/\/kinsta.com\/nl\/\",\"name\":\"Kinsta\u00ae\",\"description\":\"Snelle, veilige, premium hostingoplossingen\",\"publisher\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kinsta.com\/nl\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kinsta.com\/nl\/#organization\",\"name\":\"Kinsta\",\"url\":\"https:\/\/kinsta.com\/nl\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg\",\"contentUrl\":\"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg\",\"width\":500,\"height\":500,\"caption\":\"Kinsta\"},\"image\":{\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/\",\"https:\/\/x.com\/Kinsta_NL\",\"https:\/\/www.instagram.com\/kinstahosting\/\",\"https:\/\/www.linkedin.com\/company\/kinsta\/\",\"https:\/\/www.pinterest.com\/kinstahosting\/\",\"https:\/\/www.youtube.com\/c\/Kinsta\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63\",\"name\":\"Carlo Daniele\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\/\/kinsta.com\/nl\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g\",\"caption\":\"Carlo Daniele\"},\"description\":\"Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.\",\"sameAs\":[\"https:\/\/frammentidicodice.com\/\",\"https:\/\/x.com\/carlodaniele\"],\"url\":\"https:\/\/kinsta.com\/nl\/blog\/author\/carlodaniele\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Zo bouw je PHP-only blokken in Gutenberg","description":"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/","og_locale":"nl_NL","og_type":"article","og_title":"Zo bouw je PHP-only Gutenberg blokken","og_description":"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.","og_url":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/","og_site_name":"Kinsta\u00ae","article_publisher":"https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/","article_published_time":"2026-04-07T06:00:12+00:00","article_modified_time":"2026-04-07T07:01:03+00:00","og_image":[{"width":1470,"height":735,"url":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png","type":"image\/png"}],"author":"Carlo Daniele","twitter_card":"summary_large_image","twitter_description":"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.","twitter_image":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png","twitter_creator":"@carlodaniele","twitter_site":"@Kinsta_NL","twitter_misc":{"Geschreven door":"Carlo Daniele","Geschatte leestijd":"17 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#article","isPartOf":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/"},"author":{"name":"Carlo Daniele","@id":"https:\/\/kinsta.com\/nl\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63"},"headline":"Zo bouw je PHP-only Gutenberg blokken","datePublished":"2026-04-07T06:00:12+00:00","dateModified":"2026-04-07T07:01:03+00:00","mainEntityOfPage":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/"},"wordCount":2159,"publisher":{"@id":"https:\/\/kinsta.com\/nl\/#organization"},"image":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png","inLanguage":"nl-NL"},{"@type":"WebPage","@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/","url":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/","name":"Zo bouw je PHP-only blokken in Gutenberg","isPartOf":{"@id":"https:\/\/kinsta.com\/nl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage"},"image":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage"},"thumbnailUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png","datePublished":"2026-04-07T06:00:12+00:00","dateModified":"2026-04-07T07:01:03+00:00","description":"Laat JS, React en complexe buildprocessen achter je. Bouw Gutenberg blokken met pure PHP en deploy custom blokken naar WordPress in enkele minuten.","breadcrumb":{"@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/"]}]},{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#primaryimage","url":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png","contentUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2026\/03\/how-to-build-php-only-gutenberg-blocks.png","width":1470,"height":735},{"@type":"BreadcrumbList","@id":"https:\/\/kinsta.com\/nl\/blog\/php-only-gutenberg-blokken\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/kinsta.com\/nl\/"},{"@type":"ListItem","position":2,"name":"WordPress ontwikkeling","item":"https:\/\/kinsta.com\/nl\/onderwerpen\/wordpress-ontwikkeling\/"},{"@type":"ListItem","position":3,"name":"Zo bouw je PHP-only Gutenberg blokken"}]},{"@type":"WebSite","@id":"https:\/\/kinsta.com\/nl\/#website","url":"https:\/\/kinsta.com\/nl\/","name":"Kinsta\u00ae","description":"Snelle, veilige, premium hostingoplossingen","publisher":{"@id":"https:\/\/kinsta.com\/nl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kinsta.com\/nl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"},{"@type":"Organization","@id":"https:\/\/kinsta.com\/nl\/#organization","name":"Kinsta","url":"https:\/\/kinsta.com\/nl\/","logo":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/","url":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg","contentUrl":"https:\/\/kinsta.com\/nl\/wp-content\/uploads\/sites\/7\/2023\/12\/kinsta-logo.jpeg","width":500,"height":500,"caption":"Kinsta"},"image":{"@id":"https:\/\/kinsta.com\/nl\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Kinsta-Nederland-476213452787823\/","https:\/\/x.com\/Kinsta_NL","https:\/\/www.instagram.com\/kinstahosting\/","https:\/\/www.linkedin.com\/company\/kinsta\/","https:\/\/www.pinterest.com\/kinstahosting\/","https:\/\/www.youtube.com\/c\/Kinsta"]},{"@type":"Person","@id":"https:\/\/kinsta.com\/nl\/#\/schema\/person\/962dde02ea6f5df089b5d8d0853bbc63","name":"Carlo Daniele","image":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/kinsta.com\/nl\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/429e5568f88110fd9a409b84cb22197e?s=96&d=mm&r=g","caption":"Carlo Daniele"},"description":"Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.","sameAs":["https:\/\/frammentidicodice.com\/","https:\/\/x.com\/carlodaniele"],"url":"https:\/\/kinsta.com\/nl\/blog\/author\/carlodaniele\/"}]}},"acf":[],"_links":{"self":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts\/65163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/users\/36"}],"replies":[{"embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/comments?post=65163"}],"version-history":[{"count":7,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts\/65163\/revisions"}],"predecessor-version":[{"id":65214,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/posts\/65163\/revisions\/65214"}],"alternate":[{"embeddable":true,"hreflang":"en","title":"English","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/translations\/en"},{"embeddable":true,"hreflang":"it","title":"Italian","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/translations\/it"},{"embeddable":true,"hreflang":"ja","title":"Japanese","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/translations\/jp"},{"embeddable":true,"hreflang":"fr","title":"French","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/translations\/fr"},{"embeddable":true,"hreflang":"de","title":"German","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/translations\/de"},{"embeddable":true,"hreflang":"es","title":"Spanish","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/translations\/es"},{"embeddable":true,"hreflang":"nl","title":"Dutch","href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/translations\/nl"},{"href":"https:\/\/kinsta.com\/nl\/wp-json\/kinsta\/v1\/posts\/65163\/tree"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/media\/65164"}],"wp:attachment":[{"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/media?parent=65163"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/tags?post=65163"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/kinsta.com\/nl\/wp-json\/wp\/v2\/topic?post=65163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}