Dokumentation durchblättern
Module entwickeln
Assets & Frontend
Wie ein Modul eigenes CSS und JavaScript ausliefert: Manifest, Symlink, Blade-Direktive und der Weg über Tailwind ohne eigenes CSS.
Ein Modul kann eigenes CSS und JavaScript mitbringen. Schneespur lädt diese Dateien
während des Boot-Prozesses automatisch, ohne dass Sie Core-Dateien anfassen müssen.
Dieser Abschnitt zeigt, wie der Weg von der gebauten Datei bis zum <link>- oder
<script>-Tag im fertigen HTML verläuft — und warum es für die meisten Module sogar
ganz ohne eigenes CSS geht.
So werden Modul-Assets geladen
Der Ablauf besteht aus fünf Schritten und läuft beim Booten des Moduls von selbst ab:
- Das Modul legt gebautes CSS/JS im Verzeichnis
dist/ab. - Eine
dist/manifest.jsonlistet diese Dateien auf. - Die
ModuleAssetRegistryliest das Manifest beim Booten ein. - Es entsteht ein Symlink:
public/modules/{slug}/→modules/{slug}/dist/. - Die Blade-Direktive
@moduleAssetsgibt die<link>- und<script>-Tags aus.
Der Grund für diesen Umweg über Symlink und Manifest: Die Asset-Dateien bleiben im
Modul-Verzeichnis liegen, werden aber unter dem öffentlichen public/-Pfad erreichbar.
So bleibt jedes Modul in sich geschlossen, und der Core muss nicht wissen, welche
Dateien ein Modul mitbringt — er liest sie aus dem Manifest.
Verzeichnisstruktur
modules/my-module/
dist/
manifest.json
my-module-abc123.css
my-module-abc123.js
manifest.json
Das Manifest ist eine schlichte Liste der auszuliefernden Dateien:
[
{"type": "css", "file": "my-module-abc123.css"},
{"type": "js", "file": "my-module-abc123.js"}
]
Jeder Eintrag braucht genau zwei Felder:
type: entweder"css"oder"js"file: Dateiname innerhalb desdist/-Verzeichnisses
Der Hash-Anhang im Dateinamen (z. B. abc123) ist empfohlen, weil er für Cache-Busting
sorgt: Ändert sich der Inhalt, ändert sich der Dateiname, und Browser laden die neue
Datei statt einer veralteten aus dem Cache.
Asset-URLs
Ausgeliefert werden die Dateien unter /modules/{slug}/{file}:
/modules/my-module/my-module-abc123.css
/modules/my-module/my-module-abc123.js
Blade-Direktiven
@moduleAssets
Diese Direktive gibt alle registrierten Modul-CSS- und -JS-Dateien aus. Sie ist bereits in den Core-Layouts enthalten — Sie müssen sie also nicht selbst einbauen.
Erzeugt wird daraus:
<link rel="stylesheet" href="/modules/my-module/my-module-abc123.css">
<script src="/modules/my-module/my-module-abc123.js" defer></script>
Helfer module_asset()
Wenn Sie eine einzelne Asset-Datei innerhalb einer View ansprechen wollen, liefert
module_asset() den passenden Pfad:
module_asset('my-module', 'my-module-abc123.css');
// Returns: '/modules/my-module/my-module-abc123.css'
@lifecycleFields
Hinzugekommen in 1.1.6. Diese Direktive rendert die Formularfelder, die Module in einen
der vier Fahrer-Lebenszyklus-Momente einhängen — etwa beim Abschluss eines Einsatzes. Sie
gibt aus, was Module zuvor über die LifecycleFieldRegistry für den jeweiligen
Lebenszyklus-Punkt angemeldet haben:
@lifecycleFields(\App\Enums\LifecyclePoint::JobEnd) {{-- render driver lifecycle fields --}}
Der Grund für diesen Erweiterungspunkt: Die Fahrer-Formulare des Cores sollen sich von
Modulen ergänzen lassen, ohne dass Sie eine Core-View anfassen. Ein Modul registriert seine
Felder an der Registry, und der Core rendert sie an der passenden Stelle. Wie bei
@moduleAssets ist die Direktive bereits in den Core-Formularen platziert — ein Modul
registriert Felder, es ruft die Direktive nicht selbst auf.
Das Registrieren solcher Felder beschreibt die LifecycleFieldRegistry,
das zugehörige Feld-Interface die Interfaces-Referenz. Dieser
Abschnitt deckt nur den Frontend-/Render-Teil ab.
Der Erweiterungspunkt selbst existiert ab dieser Version. Die Module, die ihn befüllen — geplant sind unter anderem ein Inventar- und ein Grünpflege-Modul —, sind noch nicht verfügbar.
Assets bauen
Die Kern-Anwendung nutzt Tailwind CSS. Für die eigenen Assets haben Sie drei Wege — vom einfachsten zum aufwändigsten.
Variante A: Reines CSS (am einfachsten)
Schreiben Sie CSS in eine .css-Datei und legen Sie sie in dist/ ab. Mehr ist nicht
nötig.
Variante B: Build mit Vite/Webpack
Hat Ihr Modul aufwändigere Frontend-Anforderungen, bauen Sie die Assets mit einem Bundler. Das Manifest wird dann vom Build-Prozess erzeugt:
modules/my-module/
resources/
css/
module.css
js/
module.js
vite.config.js (or webpack.config.js)
package.json
dist/
manifest.json (auto-generated by build)
my-module-abc123.css
my-module-abc123.js
Variante C: Tailwind-Klassen
Da der Core Tailwind bereits lädt, können die Blade-Views eines Moduls Tailwind-Klassen direkt verwenden — ganz ohne zusätzliches CSS:
<div class="bg-white rounded-lg shadow p-4 mb-4">
<h3 class="text-sm font-medium text-gray-500">{{ $label }}</h3>
<p class="mt-2 text-lg">{{ $value }}</p>
</div>
Für die meisten Modul-Views ist das der empfohlene Weg: Sie kommen ohne eigenes CSS, ohne Build-Schritt und ohne Manifest aus.
Symlinks verwalten
Den Symlink legt der ModuleManager automatisch an:
public/modules/my-module → modules/my-module/dist
Sie müssen ihn also nicht von Hand setzen. Für die Symlinks gilt:
- Angelegt wird er, sobald ein Modul aktiviert oder gebootet wird.
- Entfernt wird er, sobald ein Modul deaktiviert wird.
- Das übergeordnete Verzeichnis
public/modules/wird bei Bedarf automatisch erstellt.
Beispiel: Widget-View mit Tailwind
Ein vollständiges, lauffähiges Widget — komplett mit Tailwind-Klassen, ohne eine einzige Zeile eigenes CSS:
{{-- resources/views/widgets/status-card.blade.php --}}
<div class="bg-white rounded-lg shadow p-4">
<div class="flex items-center gap-3">
<div class="flex-shrink-0">
<svg class="w-8 h-8 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/>
</svg>
</div>
<div>
<h3 class="text-sm font-medium text-gray-500">{{ $label }}</h3>
<p class="text-lg font-semibold text-gray-900">{{ $data['status'] ?? 'Unknown' }}</p>
</div>
</div>
</div>
Wie Sie ein solches Widget im Dashboard registrieren, steht unter
Navigation & Dashboard. Die genaue API der
hier erwähnten ModuleAssetRegistry und der übrigen Registries finden Sie unter
Registries.