# Etappe 4 – Designsystem schreiben – Design-Spezifikation - **Datum:** 2026-10-16 - **Status:** Entwurf zur Freigabe - **Autor:** Jan-Niclas Loosen (Loosen-IT), erarbeitet mit Claude - **Einordnung:** Etappe 4 der Gesamt-Spec (`2026-09-25-wp-lit-mcp-design.md` §7, §13); baut auf der Divi-Absicherung (`2026-09-29-divi-absicherung-design.md`) auf. Entscheidungen G1–G12: `docs/superpowers/notes/2026-09-28-etappe-4-entscheidungen-entwurf.md`. Datenformate: `docs/superpowers/notes/2026-09-28-etappe-4-divi-formate.md` (Divi 5.2.1). - **Annahmen** sind mit **(A…)** markiert: Punkte, die im Brainstorming nicht einzeln gefragt wurden; bei der Freigabe der Spec bestätigen oder ändern. ## 1. Ziel und Kontext ### 1.1 Problem Das Plugin liest das Designsystem (`lit/divi-design-system`: Farben, Variablen, Theme-Schriften/-Größen, Presets mit Name und ID) und kann einem Modul beim Einfügen/Ändern **ein** Modul-Preset per Name geben (`"preset": ""`). Es fehlt: - Einstellungen eines Presets lesen; Presets anlegen, ändern, löschen; Gruppen-Presets und Preset-Stapel zuweisen; Presets auf viele Seiten auf einmal ausrollen oder überall entfernen. - Globale Farben, Variablen, Design-Theme-Optionen und Schriften schreiben. - Eine Wiederherstellung: Divi 5 führt für Farben, Variablen und Presets keine serverseitige Historie (Formate §7.6). - Schleifen-Inhalte (`loop_*`, z. B. Datum oder Kategorien in Karten einer Loop-Spalte) werden immer abgelehnt (Ruling S36), mit irreführender Meldung „nur innerhalb von Divi-Schleifen“ (G12). ### 1.2 Ziele 1. Ein Corporate Design lässt sich über die Tools vollständig übernehmen: Farben, Variablen, Schriften, Theme-Optionen, Presets – und auf bestehende Seiten ausrollen. 2. Jede site-weite Änderung: Probelauf mit Diff und betroffenen Seiten, erst `confirm: true` schreibt, vorher immer ein Snapshot (G2, G6). 3. Schreiben nur über Divis eigene Funktionen, abgesichert über Manifest und Freigabe (Divi-Absicherung). 4. Schleifen-Inhalte in Modulen innerhalb einer Divi-Schleife setzen können (G12). ### 1.3 Erfolgskriterien 1. Ein Preset lässt sich lesen (Kurz- und Vollform), anlegen (aus `set`/`attrs` oder aus einem Modul), ändern, als Standard setzen und – wenn unbenutzt – löschen; die Frontend-Ausgabe entspricht einem im Builder angelegten Preset (Integrationstest gegen echtes Divi). 2. Modul- und Gruppen-Presets, auch gestapelt, lassen sich einzelnen Modulen und per Massenzuweisung vielen Seiten zuweisen; Verweise lassen sich überall entfernen. 3. Farben, Variablen, Design-Theme-Optionen und Schriften lassen sich schreiben; der Builder zeigt sie danach unverändert an. 4. Jede Änderung eines Bereichs erzeugt vorher einen Snapshot; `lit/divi-design-restore` stellt ihn mit Probelauf wieder her. 5. `{{…}}`/Vollform mit `loop_post_date` in einem Modul unter einer Spalte mit aktiver Schleife wird gespeichert; ohne Schleifen-Kontext kommt eine verständliche Ablehnung. 6. Architekturtest (Divi-Grenze) grün; alle bestehenden Tests grün; Security-Audit ohne offene kritische/hohe Punkte. ### 1.4 Nicht Teil dieser Etappe - SEO-Optionen, Logo (`divi_logo`), Button-Standards (`all_buttons_*`) (G3, A1). - MCP-Prompts und eigener Guide „Corporate Design übernehmen“ (G11) – nur Tools; Tool-Beschreibungen tragen die Reihenfolge. - Echtes Löschen von Farben (nur `inactive`, wie Divi); Löschen hochgeladener Schriften (A2). - Loop Builder **anlegen** (Schleife an einem Container einschalten/konfigurieren) – nur Inhalte innerhalb bestehender Schleifen (A3). - Snapshots von Seiteninhalten (dafür WordPress-Revisionen). ## 2. Begriffe - **Bereich:** `colors`, `variables`, `presets`, `theme_options` – Einheit für Snapshot, `design_rev` und Rechte. - **`design_rev`:** Hash über den gelesenen Rohbestand eines Bereichs; Sperre gegen gleichzeitige Änderungen (wie `tree_rev` bei Seiten). - **Änderungs-Pipeline:** gemeinsamer Ablauf aller Schreib-Tools des Designsystems (§4). - **Seiten-Umschreiber:** gemeinsamer Baustein, der Verweise in vielen Seiten ändert (§6.6). - **Fundstellen:** Seiten, Bibliothekseinträge und Theme-Builder-Layouts, die ein Preset, eine Farbe oder Variable verwenden. ## 3. Architektur ``` Tools (Abilities) Pipeline / Domäne (reines PHP) Adapter (Divi-Grenze) lit/divi-presets-set ─┐ DesignChange (Rechte→Prüfung→Diff→ Designsystem-Adapter lit/divi-colors-set ─┤ confirm→Snapshot→Schreiben→Protokoll) ├ Reader (vorhanden) lit/divi-variables-set┤──────────▶ PresetStore / ColorStore / … ──────▶ └ Writer (neu) lit/divi-theme-options-* SnapshotStore Katalog-Adapter lit/divi-design-restore DesignUsages (Fundstellen) (Gruppen-Namen, Preset- lit/divi-presets-assign ─┐ SiteRewrite (Seiten-Umschreiber) ─────▶ Attr-Mapping, Google-Fonts) lit/divi-design-detach ─┘ Seiten-Adapter (DiviSaver) ``` - Neue Divi-Aufrufe liegen nur im **Designsystem-Adapter** (Schreiben: `GlobalData::set_global_colors`, `set_global_variables`, `GlobalPreset::prepare_data`, `validate_preset_count`, `save_data`, `et_update_option`, `FontsUtility`/Divis Upload-Filter) und im **Katalog-Adapter** (`GlobalPreset::get_group_preset_default_attr`, `get_default_group_name`, `Conversion::get_preset_attrs_mapping`, `get_preset_attrs`, `et_builder_get_google_fonts`, Loop-Optionen). Jeder Eintrag steht im Manifest; nachgebaute Logik bekommt einen Fingerabdruck. Divi-Funktionen werden aufgerufen, wo möglich, statt nachgebaut. - Domänenklassen (Bestände berechnen, Diff, Prüfregeln, Überdeckungen) sind reines PHP und unit-testbar; sie arbeiten auf den Rohdaten des Adapters. - Seitenänderungen laufen über die vorhandenen Bausteine: `Parser`/`TreeEditor`/`Composer`/`Serializer` und `DiviSaver` (Revision je Seite, Cache), Rechte und Grenzen wie `GlobalUsages`/`VisibleEdits`. - Formate stammen aus Divi 5.2.1; freigegeben ist inzwischen 5.14.0. **Erster Umsetzungsschritt:** Formate und Funktionssignaturen gegen 5.14.0 prüfen und die Formate-Notiz nachführen (Spec §14 Gesamt-Spec: „nur aus Code abgeleitet“). ## 4. Änderungs-Pipeline (freigegeben) Jedes Schreib-Tool des Designsystems: 1. **Rechte** des Bereichs (§10). 2. **Eingabe prüfen:** JSON-Schema, dann fachlich (Namen, IDs, Platzhalter `{{color:…}}`/`{{var:…}}`/`{{font:…}}`, Werte über `ValueCleaner`/Composer mit denselben Sperren wie bei Modulen: Lottie, Interactions, rohes HTML/CSS ohne `unfiltered_html`). Fehler gesammelt als `validation_failed` mit `fields`. 3. **Neuen Bestand berechnen** aus aktuellem Rohbestand (live gelesen) + Änderung. 4. **Probelauf** (ohne `confirm`): `diff` (je Eintrag vorher/nachher, Eintragsart `added|changed|removed|deactivated`), `affected` (Fundstellen über `DesignUsages`, Regeln wie `UsageReport`: lesbare Seiten mit Titel, sonst Anzahl; `blocked_ids`), `design_rev`. Nichts gespeichert. 5. **Mit `confirm: true`:** `design_rev` vergleichen (sonst `conflict`, nichts geschrieben) → Snapshot → Schreiben über Divi → nach dem Schreiben zurücklesen und mit dem erwarteten Bestand vergleichen (fängt stille Fehlschläge wie bei `set_global_variables`) → Caches → Protokoll. 6. **Antwort:** `ToolResult` mit `diff`, `snapshot_id`, `log_id`, neuem `design_rev`, `warnings`. 7. **Fehler beim Schreiben oder Zurücklesen:** Snapshot zurückschreiben (`Rollback`), `WriteFailed` (`rolled_back`/`partial`). Jedes Tool nimmt **mehrere Einträge** eines Bereichs je Aufruf (ein Snapshot, ein Diff) (A4). Keine Ausnahme für „harmlose“ Änderungen: auch ein neues, unbenutztes Preset braucht Probelauf + `confirm`. ## 5. Snapshots (freigegeben) - **Speicher:** je Bereich eine Option `lit_mcp_snapshots_` (autoload aus), höchstens 20 Einträge (FIFO). Eintrag: `id`, `created` (UTC), `user_id`, `ability`, `log_id`, `size`, `data` (Rohbestand wie Divi ihn speichert; Farben inkl. der fünf Customizer-Farben aus `et_divi`). - **Größe:** Snapshot über 2 MB → Änderung abgelehnt (`snapshot_too_large`), statt ohne Sicherung zu schreiben. - **`lit/divi-design-snapshots`** (lesen): je Bereich die Liste ohne `data`, mit `cursor`/`limit`. - **`lit/divi-design-restore`** (`snapshot_id`): Probelauf = Diff Snapshot ↔ aktueller Stand; mit `confirm` Snapshot des aktuellen Stands, dann Zurückschreiben über dieselben Divi-Funktionen wie beim Schreiben. Presets: `save_data()` mit dem Snapshot-Bestand (ohne `validate_preset_count`, weil das Wiederherstellen Presets entfernen darf); verwaiste Verweise in Seiten meldet der Probelauf als Warnung. - Deinstallation entfernt die Snapshot-Optionen. ## 6. Presets ### 6.1 Identifikation - Modul-Presets über `module` (`button` oder `divi/button`), Gruppen-Presets über `group` (`font-body` oder `divi/font-body`). - Ein Preset wird über `id` oder `name` angesprochen. Namen sind in Divi nicht eindeutig: Ein mehrdeutiger Name ist ein Fehler mit den passenden IDs (wie Ruling S13a). Neue Presets mit einem schon vergebenen Namen desselben Moduls/derselben Gruppe werden abgelehnt (A5) – strenger als Divi, damit Namen beim Zuweisen eindeutig bleiben. ### 6.2 Lesen: `lit/divi-preset-get` - Eingabe: `module` oder `group`, `id` oder `name`. - Antwort: `id`, `name`, `kind`, `module`/`group`, `default` (Standard-Preset?), `set` (Einstellungen in Kurzform, soweit abbildbar), `attrs` (Vollform, nur was nicht in `set` steht), verschachtelte `group_presets` mit Namen, Werte im selben Format wie `lit-divi-node-get` (Roh-Verweise `$variable(…)$`; Namen und Platzhalter liefert `lit-divi-design-system`), `usage` (Fundstellen wie §4 Schritt 4, gekappt), `design_rev`. - `lit-divi-design-system` bleibt die Übersicht (Name, ID, Standard). ### 6.3 Anlegen und ändern: `lit/divi-presets-set` `items` = Liste von Einträgen: ```json { "module": "button", "name": "CTA primär", // oder "group": "font-body"; "id" zum Ändern "rename": "CTA Primär", // optional, nur beim Ändern "set": { "background_color": "{{color:primary}}", "text_color": "#ffffff" }, "attrs": { "button.decoration.border.desktop.value.radius": "{{var:Eckenradius}}" }, "from_node": { "post_id": 12, "id": "s0.r0.c1.m2" }, "group_presets": { "font": "Button-Schrift" }, // verschachtelte Gruppen-Presets (nur Modul-Presets) "make_default": false } ``` - Ohne `id` und ohne gleichnamiges Preset → anlegen; mit `id` (oder eindeutigem `name`) → ändern. Ändern **mischt**: genannte Pfade werden gesetzt, `null` entfernt einen Pfad/Breakpoint, Nicht-Genanntes bleibt (wie `lit-divi-update`). - `set`/`attrs` laufen durch den Composer des Moduls (`module`) bzw. des Quellmoduls der Gruppe: dieselbe Kurzform, Pfadprüfung, Platzhalter, Bereinigung und Sperren wie bei Modulen. Nur Pfade, die Divis Preset-Attribut-Mapping des Moduls kennt (`Conversion::get_preset_attrs_mapping`), sind erlaubt; Inhalte (Texte, URLs, Bilder-IDs …) werden abgelehnt (`validation_failed` mit Pfad). - **Gruppen-Presets:** nur Pfade unterhalb der Gruppe (`groupId`, z. B. `content.decoration.bodyFont`); Speicherung mit `groupName`, `groupId`, Quell-`moduleName` wie der Builder (Formate §3). - **`from_node`:** liest den Knoten (Leserecht auf die Seite), übernimmt alle Attribute, die das Preset-Mapping des Moduls als Preset-Attribute führt; Inhalte nicht. Kombinierbar mit `set`/`attrs` (gehen vor). Gruppen: nur die Pfade der Gruppe. - **`styleAttrs`/`renderAttrs`** werden serverseitig mit Divis `Conversion::get_preset_attrs(…)` berechnet, `version` = installierte Builder-Version, `created`/`updated` in Millisekunden, IDs 10 Zeichen `[0-9a-z]` (Formate §3). - **`make_default: true`:** wird Standard-Preset des Moduls/der Gruppe; Probelauf nennt alle Seiten mit Modulen dieses Typs ohne eigenes Preset als betroffen. - Schreiben: vollständiger Bestand → `prepare_data()` (Sanitize wie der Controller) → `validate_preset_count()` → `save_data()`. ### 6.4 Löschen: `lit/divi-presets-delete` - `items` = Presets (`module`/`group` + `id`/`name`). - Nur unbenutzte Presets (G5): Fundstellen in Seiten, Bibliothek, Theme Builder **und** als verschachteltes Gruppen-Preset in anderen Presets. Sonst Fehler `in_use` mit Fundstellen und dem Hinweis auf `lit/divi-design-detach`. - Ein Standard-Preset wird erst gelöscht, nachdem `default` auf `""` gesetzt ist (im selben Aufruf automatisch, im Diff sichtbar). - Schreiben wie §6.3 mit `actionType`-Semantik `DELETE_*` (kein `preset_count_decreased`); Divi-4-Altoption wie der Controller bereinigen (`remove_preset_from_legacy_option`). ### 6.5 Zuweisen an einzelne Module (`lit-divi-insert`, `lit-divi-update`, `lit-content-create`) - `"preset"`: Name **oder Liste von Namen** (Stapel, letzter gewinnt wie in Divi); `null` entfernt. Speicherung `modulePreset: [ids]`. - `"group_presets"`: `{ "": "" | ["", …] | null }`, Gruppe als Kurzname (`font-body`) oder `divi/font-body`; Zuordnung zum Attributpfad über Divis Gruppenliste des Moduls (`get_group_preset_default_attr`). Speicherung `groupPreset: { "": { presetId: [ids], groupName } }`. - **Überdeckungen (G9):** Lokale Werte des Moduls auf denselben Pfaden (Pfad + Breakpoint + Zustand) wie das Preset werden gemeldet (`warnings`: „s0.r0.c1.m2: Hintergrundfarbe, Schriftgröße überdecken ‚CTA primär‘“). `clear_overrides: true` entfernt genau diese lokalen Werte. - `lit-divi-outline` zeigt Gruppen-Presets mit Namen zusätzlich zu Modul-Presets. ### 6.6 Seiten-Umschreiber (gemeinsam für §6.7 und §6.8) - Findet Fundstellen (`DesignUsages`: lesbare Seiten, Bibliothekseinträge, Theme-Builder-Layouts; Rechte- und Theme-Builder-Regeln wie `GlobalUsages`), ändert je Seite den Baum über `TreeEditor`/Composer und speichert über `DiviSaver` (Revision je Seite, Cache, Protokoll). - Probelauf: je Seite die betroffenen Knoten (Pfad-ID, Modul, Label) und Überdeckungen; `blocked_ids` für Live-Seiten ohne `edit_post`; keine Änderung, wenn eine Seite blockiert ist (wie `GlobalEdits`). - **Grenze je Aufruf** (A6): höchstens 50 Seiten werden mit `confirm` geschrieben; die Antwort nennt `remaining`. Beide Operationen sind wiederholbar (Filter treffen bereits geänderte Module nicht mehr), der nächste Aufruf macht weiter. Über `GlobalUsages::HARD_CAP` Live-Seiten: Ablehnung wie bisher. - Seiten mit globalen Modulen: Instanzen werden nicht umgeschrieben, sondern der Bibliothekseintrag (eigene Fundstelle, F7-Regeln); nicht bearbeitbare/gesperrte Knoten (StoredNodeGuard) bleiben unverändert und werden gemeldet. - Pro Seite gilt ein frisch gelesener Baum (kein `tree_rev` nötig); schlägt eine Seite fehl, sind die bereits gespeicherten Seiten gespeichert (Revisionen in der Antwort), die Antwort meldet `partial`. ### 6.7 Massenzuweisung: `lit/divi-presets-assign` - Eingabe: `module` (Pflicht), `preset` (Name/Liste) und/oder `group_presets`, Filter: `post_ids` (optional, sonst alle Fundstellen mit diesem Modultyp), `only_without_preset` (bool) oder `only_with_preset` (Name), `clear_overrides` (bool, G9). - Probelauf → `confirm` wie §6.6. ### 6.8 Verweise überall entfernen: `lit/divi-design-detach` - Eingabe: `preset` (`module`/`group` + Name/ID) **oder** `variable` (Name/ID). Optional `post_ids`. - Preset: entfernt die ID aus `modulePreset`/`groupPreset`-Stapeln; Module fallen auf das nächste Preset im Stapel bzw. das Standard-Preset zurück (G5 a). Verschachtelte Verwendung in anderen Presets entfernt der Aufruf im selben Schritt über die Pipeline (Snapshot `presets`). - Variable: ersetzt die Referenz durch ihren aktuellen Wert als festen Wert (A7) – „Verweis entfernen“ ohne Wert würde Inhalte leeren; bei Farben entfällt detach (sie werden nur deaktiviert). - Danach ist das Löschen (§6.4, §7.2) möglich. ## 7. Farben und Variablen ### 7.1 `lit/divi-colors-set` - `items`: `{ id? | name?, "label": "Primär", "color": "#5b3a29" | "{{color:Primär}}" + "relative": {hue, saturation, lightness, opacity}, "folder"?, "status": "active"|"inactive" }`. Die fünf Hauptfarben über ihre festen Namen (`accent_color` …). - Schreiben über `set_global_colors($data, true)` (mischen), Hauptfarben nur, wenn sie geändert werden (Standardwert-Abweichung Formate §4). Neue IDs `gcid-` + 10 Zeichen. - „Löschen“ = `status: inactive`; der Probelauf nennt Fundstellen als Warnung. - Zyklen bei relativen Farben (Tiefe max. 10 wie Divi) → `validation_failed`. ### 7.2 `lit/divi-variables-set` - `items`: `{ id? | name?, "type": "numbers|strings|images|links|fonts", "label", "value", "status": "active"|"archived" }`. Echtes Löschen gibt es nicht: Divi 5.15.1 verweigert jeden Bestand, dem eine gespeicherte `gvid-`-ID fehlt (Plan 4c, Ruling V1). - Prüfung je Typ (Zahlen: CSS-Ausdruck ohne `;{}`, Links: URL, Bilder: Anhang-ID/URL der Mediathek, Schriften: §8.2, Strings: Text). - Schreiben: vollständig lesen, `stdClass` → Array, `allowedActions` und Customizer-Schriften entfernen, `set_global_variables()` (ersetzt), zurücklesen (stiller Fehlschlag bei fehlendem `variables_manager`). - Archivieren geht immer (Divi-Verhalten); der Probelauf nennt Fundstellen in Seiten, Presets und Farben als Warnung, `lit/divi-design-detach` löst die Verweise vorher (§6.8). Ein Restore behält später angelegte Variablen archiviert. ## 8. Theme-Optionen und Schriften ### 8.1 `lit/divi-theme-options-get` / `lit/divi-theme-options-update` - Whitelist (G3 a): Schriften (`heading_font`, `body_font`, `primary_nav_font`, `secondary_nav_font`, `heading_font_weight`, `body_font_weight`), Größen (`body_font_size`, `tablet_…`, `phone_…`, `body_header_size`, `tablet_header_font_size`, `phone_header_font_size`, `body_font_height`, `body_header_height`, `body_header_spacing`, `body_header_style`), Layout (`content_width`, `gutter_width`, `section_padding`, `row_padding`). - Die fünf Farben stehen in `get` (lesend), geschrieben werden sie nur über `lit/divi-colors-set` (eine Quelle, Snapshot `colors`) (A8). - `get` liefert je Feld Typ, Beschreibung, aktuellen Wert und Divi-Standard; `update` bereinigt mit Divis Customizer-Sanitize-Callbacks (Katalog-Adapter), schreibt mit `et_update_option()` und leert die Caches wie der Customizer (`remove_static_resources`, `et_pb_force_regenerate_templates`). ### 8.2 Schriften - Schriftnamen (Theme-Optionen, Presets, Schrift-Variablen) werden gegen Divis Google-Fonts-Liste, hochgeladene Schriften (`et_uploaded_fonts`) und Web-Safe-Schriften geprüft; Unbekanntes → Fehler mit ähnlichen Namen. - **`lit/divi-fonts-upload`** (G10 b): `name`, `files` (`{ "woff2": "", "woff": …, "ttf": …, "otf": … }`), `weights` (`all` oder Liste), `generic_family`. Laden mit `wp_safe_remote_get` (Größenlimit wie Medien, Grenze je Datei 5 MB (A9)), Dateityp über Inhalt prüfen (Magic Bytes), Ablage mit Divis Upload-Verzeichnis- und Dateityp-Filtern (`upload_dir_font`, `check_filetype_and_ext_font`) über einen eigenen Sideload, weil `FontsUtility::font_add()` nur echte Browser-Uploads annimmt; Eintrag in `et_uploaded_fonts` im Format von `font_add()` (Nachbau mit Fingerabdruck). Namensregeln wie Divi (Sonderzeichen, Länge, kein Google-/vorhandener Name). - Keine Snapshots für Schriften: ein Upload legt nur neu an, überschreibt nie (A2). Probelauf + `confirm` gelten trotzdem. - DSGVO: lokales Laden der Google-Fonts bleibt Theme-Einstellung; Tool-Beschreibung weist auf hochgeladene Schriften als datensparsame Variante hin. ## 9. Schleifen-Inhalte (G12) - **Kontext:** Für den Zielknoten wird der nächste Knoten auf dem Weg Wurzel → Knoten (einschließlich des Knotens selbst) gesucht, dessen `module.advanced.loop.desktop.value.enable` an ist; daraus `queryType` (`post_types`, `post_taxonomies`/`terms`, `user_roles`/Benutzer, Menü …). Genaue Regeln (Selbst vs. Vorfahre, verschachtelte Schleifen, Werte von `queryType`) werden im ersten Umsetzungsschritt aus Divi 5.14.0 abgeleitet (`LoopUtils`, `LoopContext`, `DynamicContentLoopOptions`, Visual-Builder-Logik) und in der Formate-Notiz festgehalten. - **Erlaubte Optionen:** `DynamicContentMap` liefert `loop_*`-Optionen nicht mehr verworfen, sondern getrennt je Query-Typ (Optionen aus Divis Registry, Zuordnung zum Query-Typ aus Divis Code). `DynamicContentRules::fieldsFor()` bekommt den Schleifen-Kontext; `loop_*` nur, wenn eine Schleife vorhanden ist und die Option zum Query-Typ passt. Einstellungen werden wie alle Dynamic-Content-Einstellungen je Feldtyp bereinigt, Meta-Schlüssel-Regeln S29/S30 inklusive `loop_*_meta_key_`. - **Meldungen:** ohne Schleife: „Schleifen-Inhalt "%s" braucht eine Divi-Schleife in diesem Modul oder einem übergeordneten Element (Abschnitt, Zeile, Spalte, Gruppe).“; falscher Typ: „… passt nicht zur Schleife dieses Elements (Typ: Terme).“ - **Kurzform:** Platzhalter `{{loop: