Filament custom field en custom page bouwen: zo werkt het
Terug naar blog

Filament custom field en custom page bouwen: zo werkt het

9 min leestijd

Een Filament custom field is een PHP-class die Field extendt plus één Blade view. Een custom page is een volledige Livewire-component in je panel. Met vijf bouwstenen kom je ver: custom fields, custom pages, Livewire-componenten, render hooks en een eigen theme. Een plugin is pas zinvol als je...

Een Filament custom field is een PHP-class die Field extendt plus één Blade view. Een custom page is een volledige Livewire-component in je panel. Met vijf bouwstenen kom je ver: custom fields, custom pages, Livewire-componenten, render hooks en een eigen theme. Een plugin is pas zinvol als je het in drie of meer projecten hergebruikt.

Wanneer heb je maatwerk in Filament nodig?

Je hebt maatwerk nodig zodra de standaardcomponenten je proces niet meer volgen. Dat gebeurt later dan de meeste teams denken.

Filament levert tientallen velden, kolommen en layoutcomponenten. Text inputs, selects, repeaters, builders, file uploads, rich editors. In onze uitleg over resources, forms en tables zie je hoe ver je komt met alleen configuratie.

Maar elke backoffice heeft een paar plekken waar het knelt. Concreet:

  • Een veld dat data uit een externe API toont terwijl je typt (adres, KvK, voorraad).
  • Een scherm dat geen CRUD is, zoals een importwizard of een planbord.
  • Een banner die op elke pagina moet staan, bijvoorbeeld "je werkt in de staging-omgeving".
  • Een huisstijl die verder gaat dan een primaire kleur.

Onze eigen backoffice draait op Filament. Blog, leads, afspraken, cases en een database met Magento-shops. Die is vrijwel volledig standaard Filament, en dat is precies goed: maatwerk bouw je pas als de standaard echt tekortschiet.

Welke uitbreidingsmogelijkheden heeft Filament?

Filament heeft vijf officiële uitbreidingspunten, elk voor een ander probleem. Kies het lichtste dat werkt.

BouwsteenWat het isGebruik het voorArtisan-commando
Custom form fieldClass + Blade view die state opslaatAfwijkende invoer: kaart, kleurkiezer, API-lookupmake:filament-form-field
Custom schema componentClass + view zonder eigen stateWeergave binnen een form of infolistmake:filament-schema-component
View / Livewire in schemaBlade view of Livewire-component in een formGrafiek, preview, losse interactien.v.t. (View::make, Livewire::make)
Custom pageVolledige Livewire-pagina in je panelWizards, rapportages, instellingen, planbordenmake:filament-page
Render hookInjectie van HTML op vaste plekken in de layoutBanners, scripts, extra knoppen in topbarn.v.t. (registerRenderHook)
Custom themeEigen Tailwind CSS-build voor je panelHuisstijl, eigen Tailwind-classes in viewsmake:filament-theme

De volgorde in de tabel is ook de volgorde van complexiteit. Een render hook is tien regels. Een custom field met Alpine.js en een externe API is een dag werk, inclusief tests.

Hoe maak je een Filament custom field?

Je genereert een class die Filament\Forms\Components\Field extendt en koppelt die aan een Blade view. De view regelt de binding met Livewire-state.

Het commando:

bash
php artisan make:filament-form-field LocationPicker

Dat levert een class op in App\Filament\Forms\Components:

php
namespace App\Filament\Forms\Components;

use Filament\Forms\Components\Field;

class LocationPicker extends Field
{
    protected string $view = 'filament.forms.components.location-picker';
}

En een view. De wrapper zorgt dat label, helper text en validatiefouten er hetzelfde uitzien als bij elk ander veld:

blade
<x-dynamic-component
    :component="$getFieldWrapperView()"
    :field="$field"
>
    <div x-data="{ state: $wire.{{ $applyStateBindingModifiers("\$entangle('{$getStatePath()}')") }} }">
        <input x-model="state" />
    </div>
</x-dynamic-component>

Drie functies doen het werk:

  • $getStatePath() geeft het pad naar de Livewire-property waar de waarde in staat.
  • $applyStateBindingModifiers() respecteert ->live() of debounce-instellingen uit je PHP-config.
  • $wire.$entangle() koppelt Alpine.js-state aan Livewire, zodat je client-side kunt werken zonder elke toetsaanslag naar de server te sturen.

Wat maakt een custom field goed?

Een goed custom field gedraagt zich als een native veld. Validatie, ->required(), ->disabled() en ->hidden() moeten gewoon werken. Dat krijg je gratis door Field te extenden en de wrapper te gebruiken.

Wat wij in de praktijk toevoegen:

  • Configuratiemethodes in fluent stijl, bijvoorbeeld ->defaultZoom(12). Sla de waarde op als int | Closure en lees hem uit via $this->evaluate(). Dan werken closures met $get en $record ook.
  • Geen zware JavaScript inline. Laad externe libraries via Filament's asset-systeem, niet via een