Entwicklerportal
Templates

Manifest

Kennung, Regionen, Block-Whitelist, Einstellungen und das optionale Lizenz-Feld.

Das Manifest (src/shared/manifest.ts) beschreibt das Template für Galerie, Prüfung und Barrierefreiheits-Regeln. Es ist framework-frei (kein React), weil auch die API es lädt. defineTemplateManifest aus dem SDK prüft es sofort und wirft TemplateManifestError bei Widersprüchen.

src/shared/manifest.ts
import { z } from "zod";
import { defineTemplateManifest, type TemplateManifest, type TemplateSettingsField } from "@patriotconnect/template-sdk";

export const MeinSettings = z
  .object({
    accent: z.enum(["brand", "cta", "neutral"]).default("brand"),
    width: z.enum(["narrow", "wide"]).default("wide"),
  })
  .strict();

export const MEIN_SETTINGS_FIELDS: readonly TemplateSettingsField[] = [
  { key: "accent", label: "Farbe der Zierlinien", type: "select", defaultValue: "brand",
    options: [{ value: "brand", label: "Markenfarbe" }, { value: "cta", label: "Aktionsfarbe" }, { value: "neutral", label: "Neutral" }] },
  { key: "width", label: "Breite des Inhalts", type: "select", defaultValue: "wide",
    options: [{ value: "wide", label: "Breit" }, { value: "narrow", label: "Schmal" }] },
];

export const meinTemplateManifest: TemplateManifest = defineTemplateManifest({
  id: "mein-template",
  version: "0.1.0",
  name: "Mein Template",
  description: "Ruhige Lesespalte mit Zierlinie.",
  previewImage: "data:image/svg+xml,…",
  siteKinds: ["org", "portal"],
  rendersTitleH1: true,
  regions: [
    { id: "main", label: "Hauptinhalt (Blöcke)" },
    { id: "header-main", label: "Hauptnavigation" },
    { id: "footer-1", label: "Footer: Navigation" },
    { id: "footer-2", label: "Footer: Rechtliches" },
  ],
  blockWhitelist: ["rich_text_block", "heading", "image", "feature_card_grid", "cta_banner"],
  settingsSchema: MeinSettings,
  settingsFields: MEIN_SETTINGS_FIELDS,
  // nur für buchbare Templates – siehe unten
  license: { catalogKey: "template.mein-template", edition: "enterprise" },
});

Felder

FeldBedeutung
idKebab-Case, eindeutig; Wert von Site.template bzw. Page.template. default ist als Alias für standard reserviert.
versionSemver, gleich der Version in package.json.
siteKindsorg (Gliederung, Verein), person (Personen-Website), portal. Mindestens eine.
siteRolesNur für Org-Websites: primary, campaign, microsite. Fehlt = alle.
usage["site"], ["page"] oder beides (Standard): Website-Template und/oder Übersteuerung einer Seite.
rendersTitleH1true, wenn das Template den Seitentitel selbst als H1 ausgibt – dann lässt der Editor keinen Block mit eigener H1 zu.
previewImageVorschau in der Galerie: data:image/svg+xml,…, https://… oder /media/….
licenseOptional: Lizenz-Katalogeintrag (siehe unten).

Regionen

Regionen sind die Plätze des Templates. Sie erscheinen im Menü-Editor („Menü anzeigen in …“) und bestimmen, welche Menüs die Render-Funktion erhält (props.menus["header-main"]).

  • main ist Pflicht und nimmt die Blöcke der Seite auf.
  • Üblich: header-main, footer-1, footer-2. Eigene Plätze (z. B. header-meta) sind erlaubt.
  • Fehlt ein Menü, rendert die Region nichts – eine leere Region ist kein Fehler.
  • Deklarieren Sie nur Regionen, die das Template auch zeigt.

Blöcke

Ein Template rendert keine Block-Inhalte selbst, sondern ruft props.renderBlock(block) auf. blockWhitelist bestimmt die Palette im Seiten-Editor; fehlt das Feld, sind alle Blöcke erlaubt. Gibt das Template den Titel als H1 aus, gehören Seitenkopf-Blöcke mit eigener H1 nicht in die Whitelist.

Einstellungen

Schema (settingsSchema, Zod) und Formular (settingsFields) müssen deckungsgleich sein:

  • jedes Feld hat einen Default – schema.parse({}) muss gelingen,
  • .strict() – unbekannte Schlüssel werden abgelehnt,
  • Farben nur als Auswahl von Theme-Token-Varianten (brand, cta, neutral), nie als freier Farbwert,
  • Controls: text, textarea, select, toggle, number, color, image, url.

Lizenz-Feld

Templates können ein Eintrag im Lizenz-Katalog sein (ADR-0107):

license: { catalogKey: "template.mein-template", edition: "enterprise" },
TeilRegel
catalogKeyKleinbuchstaben, Ziffern, Punkt, Bindestrich, Unterstrich; 2–80 Zeichen; beginnt mit einem Buchstaben.
editionOptional, 1–40 Zeichen: kleinste Edition, ab der das Template enthalten ist. Fehlt = jede Edition mit diesem Eintrag.

Ohne license-Feld ist ein Template lizenzfrei und in jeder Edition wählbar – so wie template-beispiel. Das Template prüft die Lizenz nie selbst; das übernimmt die Plattform (siehe Freischaltung und Lizenz).

On this page