Maak aangepaste blokken met alleen PHP. Dag oude shortcodes π₯³
Gutenberg-blokken bouwen heeft React, Node.js en een buildpipeline betekend sinds WordPress 5.0 de blokeditor introduceerde. Als je vaardigheden in PHP liggen β net als bij mij en de meerderheid van WordPress-ontwikkelaars β heeft die drempel je bijna een decennium aan de zijlijn gehouden. WordPress 7.0 verandert dit. PHP-only blocks laten je een volledig functioneel Gutenberg-blok registreren met één PHP-bestand en de autoRegister-vlag.
Je schrijft PHP. Je krijgt een blok. Geen tooling. Geen build. π₯³ In dit artikel zie je hoe PHP-only blocks werken, en doorloop je een praktijkvoorbeeld dat een klassieke shortcode vervangt door het blokequivalent.
Wat zijn PHP-only blocks?
Tot nu toe betekende het bouwen van een aangepast Gutenberg-blok het opzetten van een JavaScript-toolchain: npm install, een block.json-bestand, een buildstap met webpack.config.js of @wordpress/scripts, en een edit.js-component geschreven in JSX. Elke wijziging vereiste een compilatiestap voordat je het in de editor kon zien. Voor een PHP-ontwikkelaar die alleen een eenvoudig weergaveblok wil registreren, voelde die overhead altijd onevenredig aan voor de taak.
PHP-only blocks snijden door dit alles heen. Nu hoef je in register_block_type() alleen 'autoRegister' => true mee te geven, en WordPress regelt automatisch alles aan de JavaScript-kant via ServerSideRender. Het blok verschijnt in de inserter, toont een live preview op het canvas en genereert Inspector Controls in de zijbalk β allemaal zonder één regel JavaScript van jou.
Controls worden automatisch gegenereerd op basis van het attribuuttype:
| Attribuuttype | Gegenereerde Inspector Control |
|---|---|
string | Tekstinvoer |
integer / number | Getal-invoer |
boolean | Schakelaar |
string + enum | Dropdown-selectie |
Automatisch gegenereerde controls dekken voorlopig alleen de vier bovenstaande typen. Alles wat complexer is, zoals afbeeldingskiezers, media-uploads of geneste data, wordt nog niet ondersteund en vereist een JavaScript-geregistreerd blok. Ontwikkelaars kunnen ook afzonderlijke attributen markeren met een local-rol om ze als interne toestand aan te merken; WordPress slaat die over bij het opbouwen van de zijbalkcontrols.
PHP-only blocks zijn vandaag beschikbaar in WordPress 7.0 zonder extra afhankelijkheden. Lees meer in de officiΓ«le dev note op Make WordPress Core.
Voor wie is dit bedoeld?
Kleinere bureaus en freelancers zonder diepgaande JavaScript-expertise kunnen nu blok-editoroplossingen bouwen die volledig gebruik maken van native WordPress-functies zonder een buildpipeline aan te raken. Als je themaspecifieke aangepaste Gutenberg-blokken wilt leveren β zoals auteursvakken, pull quotes, testimonials, CTA-banners, meldingen en vergelijkbare elementen β in plaats van terug te vallen op shortcodes, helpen PHP-only blocks die drempel aanzienlijk te verlagen.
Ze zijn geen vervanging voor JavaScript-geregistreerde blokken wanneer je inline rich-text bewerking, realtime reactieve UI of geneste binnenblokken nodig hebt β maar voor een grote klasse gestructureerde weergaveblokken is dit precies de juiste balans.
De oude manier: shortcodes
VΓ³Γ³r PHP-only blocks was de praktische aanpak van een PHP-ontwikkelaar een shortcode. Hier is een eenvoudige testimonial-shortcode met drie attributen: naam van de auteur, bedrijf, een sterrenbeoordeling, plus binnenste inhoud voor de recensietekst:
function testimonial_shortcode( $atts, $content = '' ) {
$atts = shortcode_atts( [
'name' => '',
'company' => '',
'stars' => 5,
], $atts );
$stars_count = max( 1, min( 5, intval( $atts['stars'] ) ) );
$stars_html = str_repeat( 'β
', $stars_count )
. str_repeat( 'β', 5 - $stars_count );
return sprintf(
'<blockquote class="testimonial">
<p class="testimonial__stars">%s</p>
<p class="testimonial__body">%s</p>
<footer class="testimonial__attribution">
<strong>%s</strong>%s
</footer>
</blockquote>',
esc_html( $stars_html ),
wp_kses_post( $content ),
esc_html( $atts['name'] ),
$atts['company'] ? ', ' . esc_html( $atts['company'] ) : ''
);
}
add_shortcode( 'testimonial', 'testimonial_shortcode' );Gebruik:
[testimonial name="Sarah K." company="Acme Corp" stars="4"]
Saved us hours every week.
[/testimonial]Het werkt... maar het is gewoon een shortcode π€·π»ββοΈ
Hier zijn slechts een paar problemen met shortcodes:
- Onzichtbaar in de editor. De auteur ziet
[testimonial name="Sarah K." ...]in de editor, niet de weergegeven kaart. Er is geen preview. - Niet vindbaar. Je moet weten dat de shortcode bestaat en de parameternamen onthouden. Niets toont het in de UI.
- Geen native stylingcontrols. Het aanpassen van kleur, afstand of typografie vereist aangepaste CSS of extra attributen die handmatig worden gekoppeld.
- Binnenste inhoud is geen rich text. De recensietekst wordt doorgegeven als een gewone string in
$contentβ geen bewerkbaar rich-text-gebied.
Shortcodes waren het juiste hulpmiddel voor hun tijd. De blokeditor biedt iets beters, maar was moeilijk te benutten. WordPress 7.0 biedt een snelkoppeling in de vorm van PHP-only blocks.
Om duidelijk te zijn: de juiste moderne manier om een Gutenberg-blok te bouwen is nog steeds een JavaScript-geregistreerd blok met een volledig edit-component. PHP-only blocks zijn een vereenvoudigd pad β bewust beperkt tot server-gerenderde blokken die geen rijke bewerking op het canvas nodig hebben. Ze zijn geen vervanging voor JavaScript-blokken, maar een nieuwe optie voor eenvoudigere gebruikssituaties waarbij de overhead van een buildpipeline en React-componenten niet gerechtvaardigd is.
Een eenvoudigere optie: PHP-only blocks
Laten we dezelfde testimonial bouwen als een WordPress-aangepast blok met alleen PHP. Het recept: register_block_type() met 'autoRegister' => true in supports, plus een render_callback.
Hier is de volledige code voor het blok:
function my_plugin_register_testimonial_block() {
register_block_type(
'my-plugin/testimonial', // Block name: namespace/slug
array(
'title' => 'Testimonial', // Shown in the block inserter
'attributes' => array(
// string attributes generate a text input in the sidebar
'name' => array(
'type' => 'string',
'default' => '',
),
'company' => array(
'type' => 'string',
'default' => '',
),
// integer attributes generate a number input
'stars' => array(
'type' => 'integer',
'default' => 5,
),
'body' => array(
'type' => 'string',
'default' => '',
),
),
// render_callback is the PHP function that outputs the block's HTML
'render_callback' => function ( $attributes ) {
$stars_count = max( 1, min( 5, intval( $attributes['stars'] ) ) );
$stars_html = str_repeat( 'β
', $stars_count )
. str_repeat( 'β', 5 - $stars_count );
// Translatable string for screen readers β standard WordPress i18n, nothing extra needed
/* translators: %d: star rating out of 5 */
$stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );
return sprintf(
'<blockquote %s>
<p class="testimonial__stars" aria-label="%s">%s</p>
<p class="testimonial__body">%s</p>
<cite class="testimonial__attribution">
<strong>%s</strong>%s
</cite>
</blockquote>',
// Merges your class with editor-added colour, spacing, and typography styles
get_block_wrapper_attributes( array( 'class' => 'testimonial wp-block-quote' ) ),
esc_attr( $stars_label ),
esc_html( $stars_html ),
wp_kses_post( $attributes['body'] ),
esc_html( $attributes['name'] ),
$attributes['company'] ? ', ' . esc_html( $attributes['company'] ) : ''
);
},
'supports' => array(
// The key flag β tells WordPress to handle JS registration automatically
'autoRegister' => true,
// The rest unlock native colour, typography, and spacing panels in the sidebar
'color' => array(
'background' => true,
'text' => true,
),
'typography' => array(
'fontSize' => true,
),
'spacing' => array(
'padding' => true,
'margin' => true,
),
),
)
);
}
add_action( 'init', 'my_plugin_register_testimonial_block' );Het resultaat:

Een paar dingen om op te letten. Ten eerste heeft de binnenste inhoud van een shortcode geen direct equivalent in PHP-only blocks. De recensietekst wordt een string-attribuut dat wordt bewerkt via de Inspector Controls in de zijbalk β een enkelregelig tekstveld, geen bewerkbaar rich-text-gebied op het canvas. Voor een korte testimonial-quote is dat prima. Voor langere tekst heb je een JavaScript-geregistreerd blok nodig met een RichText-component.
Ten tweede voegt get_block_wrapper_attributes() je klasse samen met wat de editor toevoegt voor kleur, typografie en afstand β zodat de native stijlpanelen werken zonder extra CSS-bedrading. De render_callback ontvangt een $attributes-array die alleen de waarden bevat die de gebruiker heeft ingesteld; geen $content-parameter, omdat binnenste inhoud niet wordt ondersteund.
Wat je krijgt ten opzichte van de shortcode-versie:
- Live preview op het editorcanvas. Geen ruwe shortcode-syntaxis meer β de auteur ziet de weergegeven testimonial-kaart terwijl ze bewerken.
- Automatisch gegenereerde controls. Naam, bedrijf, tekst (tekstinvoer) en sterren (getal-invoer) verschijnen automatisch in de Inspector Controls in de zijbalk.
- Native kleur-, lettertype- en afstandspanelen. Komt van
supportsβ geen aangepaste CSS nodig. - Vindbaar. Het blok verschijnt in de inserter onder zijn naam, met een icoon.
Vertaalklaar uit de doos
Er zijn twee afzonderlijke vertaalvraagstukken bij het werken met PHP-only blocks, en het is de moeite waard duidelijk te zijn over welke welke is.
Het eerste zijn statische strings die in je PHP-template zijn ingebakken β labels, knoptekst, UI-tekst. Deze worden afgehandeld door __() en _e(), net als in elk WordPress PHP-bestand. In het bovenstaande blok is het sterrenlabel een voorbeeld:
/* translators: %d: star rating out of 5 */
$stars_label = sprintf( __( '%d out of 5 stars', 'my-plugin' ), $stars_count );Standaard WordPress-tooling pikt deze automatisch op. Niets extra's nodig.
Het tweede vraagstuk is door de gebruiker ingevoerde inhoud die is opgeslagen als blokattributen β de testimonial-tekst, de naam van de recensent, het bedrijf. Dit is de inhoud die je redacteuren daadwerkelijk in het blok typen, en __() raakt dat niet aan. Op een meertalige site moeten deze attribuutwaarden afzonderlijk in elke taal worden vertaald, en dat is iets wat WordPress niet zelf afhandelt.
Gato AI Translations for Polylang ondersteunt PHP-only blocks direct na installatie, op dezelfde manier als het Gutenberg, Bricks, Elementor en andere page builders ondersteunt. Er is geen extra instelling vereist.
Alle string-attributen worden automatisch geregistreerd voor vertaling. Als een specifiek veld niet vertaald mag worden β een interne referentie, een URL, een numerieke code opgeslagen als string β kun je het uitschakelen met een filter.
Voor het testimonial-blok in dit artikel worden de naam van de recensent, het bedrijf en de tekst allemaal automatisch vertaald β geen configuratie nodig buiten het installeren van de plugin.
Wat PHP-only blocks (nog) niet kunnen
De huidige beperkingen van PHP-only blocks:
- Geen binnenblokken of nesting. Je kunt geen andere blokken in een PHP-only block plaatsen.
- Geen rich-text bewerking op het canvas. Het
RichText-component vereist JavaScript. Tekstcontrols worden alleen als een tekstveld in de zijbalk weergegeven. - Tekstvelden in de zijbalk zijn enkelregelig. Een
string-attribuut wordt eenTextControl, geenTextareaControlβ niet ideaal voor langere tekst. - Geen afbeeldings- of mediakiezer-attributen. Ondersteuning voor afbeeldings-/bestandsupload is gepland voor een latere release via de Block Fields API.
- Editorpreview heeft een vertraging. Attribuutwijzigingen activeren een REST API-verzoek om opnieuw te renderen op de server, dus de preview wordt niet direct bijgewerkt.
Voor eenvoudige gestructureerde blokken β testimonials, CTA's, meldingen, auteursbio's, bedrijfslijsten β zijn PHP-only blocks precies wat je nodig hebt. Voor alles wat rijke bewerking op het canvas vereist, blijft JavaScript-registratie het juiste hulpmiddel.
Wat nu
WordPress 7.0's PHP-only blocks brengen blokontwikkeling binnen handbereik van elke PHP-ontwikkelaar. ΓΓ©n PHP-bestand, één aanroep van register_block_type(), en je hebt een volledig functioneel Gutenberg-blok met zijbalkcontrols, een live canvas-preview en native stijlondersteuning. Je schrijft PHP. Je krijgt een blok. Geen tooling. Geen build. Geen JavaScript.
Als je meertalige sites bouwt, werkt Gato AI Translations naadloos samen met PHP-only blocks β je inhoud is vanaf dag één vertaalbaar.
Klaar om verder te gaan?
- Developing WordPress blocks without JSX or a build process β voor ontwikkelaars die minimaal JavaScript willen toevoegen zonder een volledige buildpipeline
- Beginner WordPress Developer course β een complete basis voor blokontwikkeling