Die zwei Türen: wie wird es genutzt?
Anwendungen sprechen auf zwei verschiedenen Wegen mit Invisible — beide Türen konsumieren dieselben Definitionen, deshalb sieht alles gleich aus.
Tür 1 — PHP-Bibliothek (Anwendungsseiten)
Für Seiten, deren Aufbau Code bestimmt und deren Inhalt Live-Daten sind: tricoma-Masken, Listen, Detailseiten. Der Datenlieferant ist die Anwendung selbst — SQL, bestehende Funktionen, volle PHP-Freiheit. Kein JSON-Dokument, keine Datenquellen-Schicht, keine Surface nötig:
// 1. Daten holen (bestehendes PHP)
$rows = kunden_rest_list([...]);
// 2. Props bauen — hier lebt die Fachlogik (Töne, Links, Spalten)
$listProps = [
'columns' => [
['key' => 'name', 'label' => 'Kunde', 'type' => 'link', 'href' => 'kunde.php?id={id}'],
['key' => 'status', 'label' => 'Status', 'type' => 'badge'],
],
'rows' => $rows,
];
// 3. Innen rendern: Liste → HTML
$listHtml = invisible_render_id('component.table', $listProps);
// 4. Außen rendern: HTML in die Slots des Skeletts
echo invisible_render_id('template.app.shell', [],
['slots' => ['sidebar' => $nav, 'main' => $listHtml]]);
Der Fluss ist immer derselbe: Props gehen in Renderer hinein, HTML kommt heraus und wandert eine Ebene höher in einen Slot. Fachliche Logik (welche Zeile welchen Badge-Ton bekommt) bleibt in der Anwendung — Bausteine kennen nur semantische Vorräte (tone: success|danger), das Theme entscheidet das Aussehen.
Tür 2 — Surface-JSON (redaktionelle Seiten)
Für Seiten, deren Aufbau redaktionell gepflegt wird: Websites, Landingpages, CMS-Inhalte. Die Seite steht als JSON-Dokument (Surface) fest — dieselben Definitionen, aber die Slot-Füllung ist gespeichert statt programmiert:
{
"schemaVersion": "1.0",
"surfaceId": "kunden-landing",
"targetProfile": "web.document",
"root": {
"nodeId": "node-root",
"definition": "template.page",
"slots": {
"header": [{ "nodeId": "node-nav", "definition": "component.navigation",
"props": { "brand": "tricoma", "items": ["..."] } }],
"main": [{ "nodeId": "node-hero", "definition": "section.hero",
"props": { "title": "…" }, "hideOn": ["mobile"] }]
}
}
}
Rendern: invisible_render_surface($surface). Nur an dieser Tür gibt es Datenquellen-Bindings ($bind) — weil hier kein Programmierer die Daten heranträgt. Die Werkzeuge zum visuellen Bauen und Publizieren solcher Seiten (Builder, Publish-Workflow) sind das CMS-Produkt auf dem Framework — seit 2026-08-10 in archiv/.
Welche Tür wofür?
| Aspekt | Tür 1 — PHP | Tür 2 — Surface-JSON |
|---|---|---|
| Seitentyp | Anwendung (Masken, Listen, Dashboards) | redaktionell (Website, Landingpage) |
| Aufbau bestimmt | Code, pro Request | gespeichertes Dokument |
| Daten kommen von | der Anwendung selbst (SQL, Funktionen) | Datenquellen-Bindings ($bind) |
| Surface nötig? | nein | ja — die Surface IST die Seite |
Der Shop ist die Mischung: Aufbau der Produktseite redaktionell (Tür 2), die Produktdaten zur Laufzeit aus der Anwendung.
Bausteine bauen (Entwickler)
Als Ordner unter definitions/<ebene>/<name>/ mit Manifest, Props-Schema, Renderer, CSS und Demo (Checkliste: definitions/README.md). npm run build validiert streng und macht den Baustein überall gleichzeitig verfügbar. Durchsuchen: UI-Kit-Galerie, Tokens: Token-Browser.