Zum Hauptinhalt springen
Schneespur
Dokumentation durchblättern

Module entwickeln

Template-Slots

Über Template-Slots fügt ein Modul Blade-Inhalte an festen Punkten der Layouts ein, ohne Core-Views zu verändern — mit append, replace und Berechtigungsprüfung.

Template-Slots sind vordefinierte Einfügepunkte in den Layouts der Anwendung. Ein Modul kann an diesen Punkten eigenen Blade-Inhalt ausgeben, ohne die Core-Views anzufassen. Genau darin liegt der Zweck: Sie erweitern die Oberfläche, ohne Dateien zu bearbeiten, die beim nächsten Update überschrieben werden — so bleiben Aktualisierungen konfliktfrei.

Wie Slots funktionieren

Ein Slot besteht aus zwei Hälften: Das Core-Layout markiert die Stelle, und Ihr Modul trägt Inhalt dafür ein.

Im Blade-Layout (Core)

Das Layout enthält an der vorgesehenen Stelle eine Direktive:

@extensionSlot('admin.content.after')

Diese Direktive ruft intern SlotRegistry::render('admin.content.after', $user) auf und gibt das gesammelte HTML aus. Sie selbst schreiben diese Direktive nicht — sie steht bereits in den Core-Layouts. Ihre Aufgabe ist nur, Inhalt für den passenden Slot-Namen anzumelden.

Im Modul (Registrierung)

Die Anmeldung läuft über die SlotRegistry, die Sie im boot() Ihres ServiceProviders auflösen:

$slots = app(SlotRegistry::class);

// Inhalt anhängen — mehrere Module dürfen denselben Slot bestücken
$slots->append('admin.content.after', 'my-module::my-partial', ['key' => 'value']);

// Oder den Slot vollständig ersetzen (last-wins)
$slots->replace('admin.content.before', 'my-module::replacement');

Der Unterschied zwischen append und replace ist bewusst gewählt: append ist additiv und verträglich — beliebig viele Module können nebeneinander an denselben Slot anbauen. replace ersetzt den gesamten Slot-Inhalt und ist deshalb dosiert einzusetzen.

Verfügbare Slots

Welche Slots es gibt, hängt vom Layout ab. Drei Layouts stellen Einfügepunkte bereit: das Admin-, das Fahrer- und das Portal-Layout.

Admin-Layout (layouts/admin.blade.php)

Slot-NameOrtEinsatzzweck
admin.head.afterim <head>, nach dem Core-CSSeigene Stylesheets, Meta-Tags
admin.sidebar.before-navüber der Navigation in der SidebarModul-Branding, Hinweise
admin.sidebar.after-navunter der Navigation in der Sidebarweitere Links, Status-Infos
admin.content.beforevor dem HauptinhaltBanner, Warnungen
admin.content.afternach dem HauptinhaltFooter-Widgets, Debug-Infos

Fahrer-Layout (layouts/driver.blade.php)

Slot-NameOrtEinsatzzweck
driver.head.afterim <head>, nach dem Core-CSSeigene Stylesheets
driver.topbar.actionsin der Top-Leiste, AktionsbereichSchnellaktions-Buttons
driver.content.beforevor dem HauptinhaltHinweise, Warnmeldungen
driver.content.afternach dem Hauptinhaltzusätzliche Funktionen
driver.bottom-nav.afternach der unteren Navigationweitere Navigationspunkte

Portal-Layout (layouts/portal.blade.php)

Slot-NameOrtEinsatzzweck
portal.head.afterim <head>, nach dem Core-CSSeigene Stylesheets
portal.nav.afternach den Portal-Navigationspunktenweitere Navigationslinks
portal.content.beforevor dem HauptinhaltHinweise, saisonale Infos
portal.content.afternach dem Hauptinhaltzusätzliche Abschnitte
portal.footer.beforevor dem Footerrechtliche Hinweise, Links

Die Slot-API

Anhängen mit append

Mehrere Module dürfen an denselben Slot anhängen. Der Inhalt wird der Reihe nach gerendert, gesteuert über order:

$slots->append(
    slotName: 'admin.content.after',
    viewPath: 'my-module::partials.info-panel',
    data: ['message' => 'Hello from module'],
    order: 100,           // Sortierreihenfolge (kleiner = früher)
    permission: 'settings.view', // optional: nur rendern, wenn der Nutzer diese Berechtigung hat
);

Über order legen Sie fest, an welcher Position Ihr Inhalt im Slot erscheint, wenn dort auch andere Module anbauen — ein kleinerer Wert rückt nach vorn. So bleibt die Reihenfolge vorhersagbar, auch wenn Sie nicht wissen, welche Module sonst noch aktiv sind.

Ersetzen mit replace

replace ersetzt den gesamten Slot-Inhalt. Wenn mehrere Module denselben Slot ersetzen, gewinnt das zuletzt registrierte (mit einem Warneintrag im Log). Setzen Sie replace deshalb sparsam ein — der Warnhinweis ist Ihr Signal, dass sich zwei Module in die Quere kommen.

$slots->replace(
    slotName: 'admin.sidebar.before-nav',
    viewPath: 'my-module::sidebar-header',
    data: [],
    permission: null,
);

Berechtigungsprüfung

Geben Sie eine permission an, wird der Slot-Inhalt nur für Nutzer gerendert, die diese Berechtigung besitzen. So lässt sich Inhalt gezielt auf bestimmte Rollen beschränken, ohne die Prüfung in der View selbst zu wiederholen:

$slots->append('admin.content.after', 'my-module::admin-only', [], 100, 'settings.edit');
// Nur sichtbar für Nutzer mit der Berechtigung 'settings.edit'

Welche Berechtigungen es gibt und wie ein Modul eigene anmeldet, steht unter Berechtigungen und Rollen.

Beispiel: ein Banner einfügen

Im boot() des ServiceProviders melden Sie das Partial an …

// Im boot() des ServiceProviders
$slots = app(SlotRegistry::class);
$slots->append('admin.content.before', 'my-module::banners.update-available', [
    'version' => '2.0.0',
], 50);

… und die zugehörige Blade-View rendert den eigentlichen Inhalt:

{{-- resources/views/banners/update-available.blade.php --}}
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4">
    <p class="text-blue-800">
        Module-Update {{ $version }} verfügbar.
    </p>
</div>

Die per data übergebenen Werte stehen in der View als Variablen zur Verfügung — hier $version.

Beispiel: einen Tab im Portal ergänzen

Oft gehören zwei Slots zusammen: einer für den Navigationspunkt, einer für den Inhalt, den er zeigt. So fügen Sie dem Portal einen eigenen Bereich hinzu:

// Navigationslink anhängen
$slots->append('portal.nav.after', 'my-module::nav.documents-link');

// Inhaltsabschnitt anhängen
$slots->append('portal.content.after', 'my-module::portal.documents-section');

Slots sind nur einer von mehreren Erweiterungspunkten, die ein ServiceProvider anmeldet. Wie die SlotRegistry neben den übrigen Registries in den Boot-Ablauf eines Moduls passt, zeigt Das ServiceProvider-Muster; die vollständige Liste der Registries finden Sie unter Registries.