Zum Hauptinhalt springen

Full-Site Template Architektur

Dieses Dokument erklärt, wie das Template-System für Center-Websites funktioniert – von der v0-Generierung bis zur Integration in CockpitOS.


Konzept: Smartphone mit unterschiedlicher Hülle

Website-Templates sind Layout-Skins über der gleichen technischen Struktur – wie ein Smartphone: gleiche Technik innen, anderes Aussehen durch die Hülle.

  • Gleiche Funktionalität: Home, Shops, News, Services, Centerplan, Kontakt – alle Seiten
  • Gleiche Daten: Kommen aus dem CockpitOS-Dashboard (zentrale Datenquelle)
  • Anderes Design: Layout, Farben, Typografie, Karten-Style – dein v0-Template

Das Template definiert die Hülle, nicht die Logik. Chatbot und Centerplan (WayfindingMap) sind globale CockpitOS-Komponenten – sie werden injiziert, nicht im Template implementiert.


Architektur-Übersicht

┌─────────────────────────────────────────────────────────────────┐
│ COCKPITOS DASHBOARD │
│ Center-Konfiguration, Shops, News, Events, Services, etc. │
└─────────────────────────────┬───────────────────────────────────┘
│ Daten (API)

┌─────────────────────────────────────────────────────────────────┐
│ CENTER-WEBSITE (Next.js) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Layout (centerConfig, websiteTemplate) │ │
│ │ ├── Template-Layout? (Header + Footer) ODER Standard │ │
│ │ ├── {children} = Page Content │ │
│ │ └── Chatbot, MetaTags, Analytics (global) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────▼─────────────────────────────────┐ │
│ │ Page (z.B. /shops) │ │
│ │ getPageComponent(template, 'shops') │ │
│ │ ├── Template-Shops? → pages/shops.tsx (v0) │ │
│ │ └── ODER ShopsPageClient (Standard) │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

Datenfluss

  1. Center aktivwebsiteTemplate aus DB (z.B. 'cev-ai-theme' oder null)
  2. Layout: Wenn Template Layout hat → CevLayout (bzw. Template-Layout) umschließt {children}, sonst Standard (SiteHeader + ConditionalFooter)
  3. Seite: getPageComponent(template, pageType) → Template-Komponente ODER Standard
  4. Props: Server lädt Daten (Shops, News, etc.) und übergibt sie an die Komponente

Fallback: Kein Template oder Template hat keine Komponente für diese Seite → Standard-CockpitOS-Komponente.


Seiten-Typen (PageTypes)

PageTypeRouteTemplate-DateiStandard-Komponente
home/{slug}index.tsxCenterHomepage
shops/{slug}/shopspages/shops.tsxShopsPageClient
shop-detail/{slug}/shops/[shopSlug]pages/shop-detail.tsxShopDetailClient
aktuelles/{slug}/aktuellespages/aktuelles.tsxAktuellesPageClient
news-detail/{slug}/aktuelles/news/[id]pages/news-detail.tsxContentDetailClient
event-detail/{slug}/aktuelles/events/[id]pages/event-detail.tsxContentDetailClient
offer-detail/{slug}/aktuelles/angebote/[id]pages/offer-detail.tsxContentDetailClient
services/{slug}/servicespages/services.tsxServicesPageClient
service-detail/{slug}/services/[slug]pages/service-detail.tsxServiceDetailClient
wayfinding/{slug}/wayfindingpages/wayfinding.tsxWayfindingPageClient
gastronomy/{slug}/gastronomypages/gastronomy.tsxGastronomyPageClient
restaurant-detail/{slug}/gastronomy/[id]pages/restaurant-detail.tsxRestaurantDetailClient
offices/{slug}/officespages/offices.tsxGesundheitszentrumPageClient
parking/{slug}/parkingpages/parking.tsxParkingPageClient
opening-hours/{slug}/opening-hourspages/opening-hours.tsxOpeningHoursPageClient
impressum/{slug}/impressumpages/impressum.tsxImpressumPageClient
datenschutz/{slug}/datenschutzpages/datenschutz.tsxDatenschutzPageClient
kontakt/{slug}/kontaktpages/kontakt.tsxContactPageClient
to-go/{slug}/to-go/[qrCodeId]pages/to-go.tsxToGoPageClient

Registry & Integration

Templates werden in apps/center-website/lib/template-registry.ts registriert:

// Layout (Header + Footer)
const TEMPLATE_LAYOUT_REGISTRY = {
'cev-ai-theme': dynamic(() => import('@/components/templates/cev-ai-theme/layout').then(m => m.CevLayout)),
};

// Pro-Seite Komponenten
const TEMPLATE_PAGE_REGISTRY = {
'cev-ai-theme': {
shops: dynamic(() => import('@/components/templates/cev-ai-theme/pages/shops').then(m => m.default)),
aktuelles: dynamic(() => import('@/components/templates/cev-ai-theme/pages/aktuelles').then(m => m.default)),
// ... weitere Seiten
},
};

Neues Template hinzufügen:

  1. v0 generiert Template nach Website Prompt
  2. ZIP herunterladen, entpacken
  3. Nach apps/center-website/components/templates/[name]/ verschieben
  4. In template-registry.ts eintragen (Layout + Pages)
  5. Daten-Anbindung: Route anpassen – z.B. loadShops für shops-Seite, loadCenterplan für shop-detail (Centerplan mit Shop-Highlight)
  6. Im Dashboard approven (TemplateSubmission)
  7. Center: Tab Website → Aktivierung → Template auswählen

Integration-Erkenntnisse (CEV): Shops-Seite braucht shops-Prop (loadShops); Shop-Detail braucht floors-Prop (loadCenterplan) und CenterPlanEmbed-Slot. Details siehe Website Prompt – Integration-Erkenntnisse.


Sicherheit für bestehende Center

  • websiteTemplate = null (Standard) → Keine Änderung, Palais Vest etc. nutzen weiterhin das Standard-Layout
  • Migration additiv: Nur neue Spalte websiteTemplate, keine Datenänderung
  • Fallback: Template unbekannt oder Seite nicht vorhanden → Standard-Komponente

Workflow für Content Creator

  1. Prompt kopierenWebsite Template Prompt (ab TASK)
  2. Screenshots – Sektionsweise (Hero, Karten, Footer) für v0
  3. v0 – Screenshots + Prompt einfügen, generieren lassen
  4. ZIP – Herunterladen, prüfen
  5. Upload – Dashboard → Templates → Hochladen
  6. Integration – Developer: ins Repo übernehmen, Registry eintragen, approven

Verwandte Dokumentation

Nutzungsstatistik: Seitenaufrufe werden anonymisiert erfasst. Im Umami-Dashboard nach diesem Pfad filtern: /templates/full-site-template-architektur