De traditionele ontwikkeling van WordPress thema’s is gebaseerd op het herhalen van header en footer markup in verschillende template bestanden. Elke keer dat je een navigatiemenu of voettekstelement bijwerkt, moet je elk templatebestand met deze opmaak opzoeken en de benodigde wijzigingen op meerdere locaties doorvoeren. Dit zorgt voor algemene onderhoudskosten en verhoogt het risico op inconsistenties op je site.
Radicle brengt de Blade templating engine van Laravel naar WordPress via de op componenten gebaseerde architectuur van Acorn. In plaats van het verspreiden van markup over template bestanden, definieer je herbruikbare componenten één keer en refereer je ernaar in je thema. Als je een UI element moet bijwerken, pas je een enkel componentbestand aan in plaats van tientallen templates te doorzoeken.
Waarom WordPress template ontwikkeling een component-gebaseerde architectuur nodig heeft
WordPress slaat templates op in een themamappenstructuur waar header.php en footer.php in elk paginatemplate verschijnen via get_header() en get_footer() aanroepen. Dit werkt voor basissites, maar veroorzaakt problemen bij het schalen over complexe projecten.
Een site met custom berichttypes, landingspagina’s en marketingtemplates bevat bijvoorbeeld dezelfde navigatieopmaak, footer structuur en zijbalkelementen in elk templatebestand. Hierdoor moet je meerdere templatebestanden doorzoeken om een nieuw menu-item toe te voegen of een contactformulier in de voettekst bij te werken.
Radicle organiseert Blade templates in resources/views/ met aparte mappen voor layouts, componenten en blokken:
components. Deze map bevat zelfstandige UI elementen zoals headers en knoppen.layouts. Deze bevat structurele templates die de paginastructuur definiëren.blocks.Je slaat hier bloktemplates op die integreren met de WordPress Site Editor.
Deze organisatie creëert een enkele bron voor elk UI element. Een x-heading component definieert heading markup en styling op één locatie. Dus wanneer je dit component in verschillende templates gebruikt, verwijst Blade naar deze ene definitie. Als je de component bijwerkt, wordt elke instantie op je site bijgewerkt.
Hoe je primaire layouts maakt die dubbele code elimineren
In plaats van navigatie- en footer markup te dupliceren, kun je template inheritance gebruiken om een bovenliggende layout te maken die de site definieert.
Een layout begint met een Blade component bestand in resources/views/components/. Het bestand layout.blade.php definieert de HTML-structuur die de paginacontent wrapt. Denk aan de doctype, head sectie met metatags en asset references, navigatiestructuur en footer elementen. Het belangrijkste element in een layout is de $slot variabele, die Blade gebruikt als het injectiepunt voor de content.
<html>
<head>
<title>{{ $title ?? 'My Site' }}</title>
</head>
<body>
<nav>
<!-- Navigation markup -->
</nav>
<main>
{{ $slot }}
</main>
<footer>
<!-- Footer markup -->
</footer>
</body>
</html>
Child templates breiden deze layout uit met behulp van Blade’s component syntax. Een paginatemplate wrapt zijn inhoud in de x-layout component tags. Blade verwerkt dit door de layout component te renderen en de child content te injecteren waar de $slot variabele verschijnt:
<x-layout>
<h1>Page Title</h1>
<p>Page content goes here.</p>
</x-layout>
Named slots bieden extra injectiepunten voor dynamische content (zoals paginatitels). In plaats van een standaard slot te accepteren, definieer je specifieke slots met namen. De x-slot component met een name attribuut geeft inhoud door aan deze aangewezen locaties:
<x-layout>
<x-slot name="title">
Custom Page Title
</x-slot>
<h1>Page Heading</h1>
<p>Page content.</p>
</x-layout>
De layout component heeft toegang tot de genoemde sleuven via variabelen die overeenkomen met de named slots. Zo kun je content injecteren in meerdere layoutlocaties vanuit een enkel child template.
Herbruikbare UI componenten maken voor consistente designpatronen
Blade componenten centraliseren styling en opmaak voor gemeenschappelijke interface elementen.
In plaats van het schrijven van knop markup met Tailwind classes in elk template, maak je een knopcomponent die de markup wrapt. Het component accepteert ‘props’ voor aanpassingen terwijl de basisstyling consistent blijft.
Het gebruik van het x-heading component met andere typografiecomponenten is hier een goed voorbeeld van. Het accepteert een level prop die het HTML-element bepaalt (h1, h2, h3) en een size prop die de visuele schaal bepaalt. Het component koppelt deze props intern aan Tailwind klassen, waardoor de implementatiedetails gescheiden blijven.
<x-heading level="h1" size="3xl">
Main Page Title
</x-heading>
<x-heading level="h2" size="2xl">
Section Heading
</x-heading>
Het componentenbestand in resources/views/components/heading.blade.php definieert de opmaak- en stylinglogica met behulp van Blade’s @props richtlijn om geaccepteerde eigenschappen en hun standaardwaarden te definiëren. Elk component construeert het juiste HTML element met klassen gebaseerd op de prop waarden.
Een x-link component volgt hetzelfde patroon met variantondersteuning voor verschillende linkstijlen en een variant prop schakelt tussen standaard, knop en niet gestileerde presentaties.
Met UI componenten zoals x-button kun je hetzelfde bereiken met interactieve elementen. Het button component ondersteunt grootte en variant props voor verschillende knopstijlen. Als je het combineert met een framework zoals Alpine.js via het x-modal component, kun je interacties afhandelen zonder JavaScript te verspreiden over templates:
<x-button variant="primary" @click="showModal = true">
Open Modal
</x-button>
<x-modal x-show="showModal">
<p>Modal content</p>
</x-modal>
Props werken goed voor strings, booleans en andere eenvoudige gegevens. Slots zijn beter voor complexe inhoud die opmaak bevat. Het modal component gebruikt bijvoorbeeld een standaard slot om de volledige modale inhoud te accepteren in plaats van HTML door te geven via een prop.
WordPress gegevens verbinden met Blade templates met view composers
Met view composers kun je gegevens uit meerdere bronnen samenvoegen voordat je een template rendert. Hier maak je een composer klasse die het ophalen en transformeren van gegevens afhandelt in plaats van posts rechtstreeks in templates te bevragen. In plaats daarvan ontvangt de template gestructureerde gegevens om weer te geven.
Radicle’s Post model vereenvoudigt het werken met WordPress berichtgegevens met behulp van een paar verschillende methoden:
title()geeft de titel van het bericht terug.- De methode
content()haalt gefilterde berichtinhoud op. excerpt()accepteert een aantal woorden en genereert een uittreksel.permalink()retourneert de URL van de post.
Voor uitgelichte afbeeldingen controleert hasThumbnail() of er een afbeelding bestaat en thumbnail() haalt de HTML-afbeelding met een opgegeven grootte op:
$post = Post::find(123);
echo $post->title();
echo $post->excerpt(30);
if ($post->hasThumbnail()) {
echo $post->thumbnail('large');
}
De View composer klassen leven in app/View/Composers/ en breiden RootsAcornViewComposer uit. De klasse definieert op welke weergaven het van toepassing is via de beschermde statische property $views, die een array van templatenamen accepteert. Voor een voorpaginacomposer specificeer je 'front-page' om de front-page.blade.php template te targeten:
namespace AppViewComposers;
use AppModelsPost;
use RootsAcornViewComposer;
class FrontPage extends Composer
{
protected static $views = ['front-page'];
public function with()
{
return [
'recentPosts' => Post::recent(6)->get(),
'totalPosts' => Post::published()->count(),
];
}
}
De methode with() retourneert een array waarvan de sleutels variabele namen worden in de template. De waarden kunnen Eloquent verzamelingen, individuele modellen of een andere gegevensstructuur zijn. Hoe dan ook, deze methode wordt uitgevoerd voordat een template de gegevens rendert en voorbereidt.
De template front-page.blade.php heeft direct toegang tot deze variabelen. Blade’s @foreach directive loopt door berichten en elke iteratie geeft toegang tot de Post modelmethoden:
<div class="posts-grid">
@foreach ($recentPosts as $post)
<article>
@if ($post->hasThumbnail())
<img src="{{ $post->thumbnail('medium') }}" alt="{{ $post->title() }}">
@endif
<h2>
<a href="{{ $post->permalink() }}">{{ $post->title() }}</a>
</h2>
<p>{{ $post->excerpt(20) }}</p>
</article>
@endforeach
</div>
<p>Total posts: {{ $totalPosts }}</p>
In dit patroon zorgt de composer voor query’s en gegevenstransformatie, terwijl de template zich richt op opmaak en weergave logica. Als je de datastructuur moet aanpassen of nieuwe query’s moet toevoegen, werk je de composer bij zonder de templatebestanden aan te raken.
Bouwstenen voor de WordPress Site Editor met Blade rendering
Radicle gebruikt server-side rendering voor Site Editor Blocks via Blade templates. Het JavaScript editor component zorgt voor de Block interface in de WordPress admin, en het Blade template zorgt voor de output aan de frot-end.
Hierdoor kun je Block interfaces bouwen met React (bijvoorbeeld) terwijl je productie HTML rendert met Blade.
Het wp acorn make:block commando genereert drie bestanden voor elk Block:
- Een PHP klasse in
app/Blocks/beheert de server-side logica. - De JSX component in
resources/js/editor/definieert de Block Editor interface. - Blade templates in
resources/views/blocks/renderen de frontend uitvoer.
Een commando wp acorn make:block latest-posts maakt LatestPosts.php, latest-posts.block.jsx, en latest-posts.blade.php. Het JSX-bestand definieert de attributen en editor besturingselementen van het blok, terwijl de dynamische blokken InspectorControls gebruiken om instellingen toe te voegen in de zijbalk van het blok. Je importeert besturingselementen van @wordpress/components en stelt ze samen in een instellingeninterface.
import { InspectorControls } from '@wordpress/block-editor';
import { RangeControl, ToggleControl, RadioControl } from '@wordpress/components';
export const attributes = {
posts: { type: 'number', default: 5 },
displayFeaturedImage: { type: 'boolean', default: false },
postLayout: { type: 'string', default: 'list' },
};
export const edit = ({ attributes, setAttributes }) => {
return (
<>
<InspectorControls>
<RangeControl
label="Number of posts"
value={attributes.posts}
onChange={(value) => setAttributes({ posts: value })}
min={1}
max={10}
/>
<ToggleControl
label="Display featured image"
checked={attributes.displayFeaturedImage}
onChange={(value) => setAttributes({ displayFeaturedImage: value })}
/>
<RadioControl
label="Layout"
selected={attributes.postLayout}
options={[
{ label: 'List', value: 'list' },
{ label: 'Grid', value: 'grid' },
]}
onChange={(value) => setAttributes({ postLayout: value })}
/>
</InspectorControls>
</>
);
};
Het render_block filter in BlocksServiceProvider.php onderschept het renderen van het Blok en geeft attributen door aan het Blade template. Het ontvangt ook de Block inhoud en Block gegevens. Je controleert de Block naam, vraagt de benodigde gegevens op en retourneert de gerenderde Blade weergave:
add_filter('render_block', function ($block_content, $block) {
if ($block['blockName'] === 'radicle/latest-posts') {
$attributes = $block['attrs'] ?? [];
$posts = get_posts([
'numberposts' => $attributes['posts'] ?? 5,
'post_status' => 'publish',
]);
return view('blocks.latest-posts', [
'posts' => $posts,
'displayFeaturedImage' => $attributes['displayFeaturedImage'] ?? false,
'postLayout' => $attributes['postLayout'] ?? 'list',
]);
}
return $block_content;
}, 10, 2);
Het Blade template gebruikt PHP arrays om voorwaardelijke layouts te beheren. Hier definieer je layout configuraties als geneste arrays die layout namen toewijzen aan CSS klassen en HTML elementen.
@php
$layoutConfig = [
'grid' => [
'container' => 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6',
'element' => 'div',
],
'list' => [
'container' => 'space-y-6',
'element' => 'div',
],
];
$config = $layoutConfig[$postLayout];
@endphp
<div class="{{ $config['container'] }}">
@foreach ($posts as $post)
<article>
@if ($displayFeaturedImage && has_post_thumbnail($post))
{{ get_the_post_thumbnail($post, 'medium') }}
@endif
<h3>{{ $post->post_title }}</h3>
</article>
@endforeach
</div>
Dit patroon creëert flexibele blokken waarin editorbesturingselementen de uitvoer aan de voorkant aanpassen zonder de logica van het template te dupliceren: JavaScript regelt de gebruikersinterface, PHP regelt gegevensquery’s en Blade regelt de opmaakstructuur.
Hoe Kinsta’s caching de prestaties van Blade’s gecompileerde weergave verbetert
Blade compilatie converteert .blade.php templates naar gewone PHP code. Nadat Blade een volledige parse van het template en de Blade syntax heeft voltooid, slaat het een gecompileerd bestand op in storage/framework/views/. Deze compilatie gebeurt één keer per templatewijziging in plaats van bij elke paginalading, maar volgende verzoeken slaan de compilatie over en voeren PHP uit in de cache.
Het proces zet Blade directives om in PHP functies. Bijvoorbeeld, de @foreach richtlijn wordt een foreach loop; de {{ $variable }} syntax wordt een echo statement met escaping.
Kinsta’s caching op serverniveau (zowel edge caching als Redis object caching) werken samen met de compilatiecache van Blade om meerdere prestatieniveaus te creëren. De gecompileerde views van Blade bevinden zich tussen deze lagen, die templateuitvoeringstijden bieden die profiteren van zowel upstream caching als downstream optimalisatie.
Tijdens de deployment wist Blade de cache wanneer je templatewijzigingen naar test- of productieomgevingen pusht. Hoewel Blade templatewijzigingen detecteert tijdens de ontwikkeling, moeten je deploymentprocessen het wissen van de view cache bevatten door php artisan view:clear of wp acorn view:clear uit te voeren in je deployment script.
Voor moderne WordPress thema ontwikkeling zijn Radicle en Kinsta vereist
De combinatie van Radicle’s Laravel-geïnspireerde structuur en Kinsta’s managed hosting infrastructuur geeft je een basis voor het schalen van WordPress projecten. Bureaus die meerdere klantensites beheren kunnen consistente componentpatronen gebruiken voor verschillende projecten. Voor ontwikkelaars kun je werken met vertrouwde Laravel conventies met behoud van compatibiliteit met WordPress.
Je volgende stap hangt af van je huidige setup. Als je nieuw begint, begin dan met het installeren van Radicle en maak je eerste Blade component. Als je een bestaand thema migreert, identificeer dan herhalende markup patronen en zet ze één voor één om naar componenten. Concentreer je op gebieden met een hoge waarde, zoals navigatie, header en footerteksten, waar componenten direct voordeel opleveren.
Als je managed WordPress hosting nodig hebt die moderne ontwikkelworkflows ondersteunt, dan biedt Kinsta functionaliteit die werkt met tools zoals Radicle en Acorn.