# Divi-Kurzform Neue Divi-Inhalte beschreibt man als JSON-Knoten. `lit-divi-insert` (in `nodes`) und `lit-content-create` (in `divi`) nehmen dieselbe Form. Jeder Knoten hat einen `type`; dazu Kurzform-Felder, optional `label` (Admin-Label), `preset` (Name oder Liste von Namen von Modul-Presets aus `lit-divi-design-system`), `group_presets` (Gruppen-Presets, siehe „Presets zuweisen“) und `attrs` (Vollform, siehe `divi-attrs`). Kurz- und Vollform lassen sich kombinieren, aber nicht für denselben Pfad (dann Fehler `validation_failed` mit dem Pfad). ## Aufbau ```json { "type": "section", "label": "Hero", "background_color": "{{color:primary}}", "rows": [ { "columns": "1_3,2_3", "modules": [ [ { "type": "image", "image_id": 33 } ], [ { "type": "heading", "text": "Willkommen", "level": "h1" }, { "type": "text", "content": "

Seit 1987 in Köln.

" }, { "type": "button", "text": "Termin buchen", "url": "/kontakt", "preset": "CTA primär" } ] ] } ] } ``` - **Abschnitt** (`section`): `rows` (Zeilen) oder – für eine einspaltige Zeile – direkt `modules`; `section_type: "fullwidth"` für Vollbreite-Abschnitte (dann nur `fullwidth-…`-Module in `modules`); `background_color`. Spezialabschnitte (specialty) nur im Divi-Builder bauen. - **Zeile** (`row`): `columns` = Breiten als Brüche, die zusammen 1 ergeben (`"4_4"`, `"1_2,1_2"`, `"1_3,2_3"`, `"1_4,1_4,1_2"`, auch `1_5`, `2_5`, `3_5` wie im Divi-Builder – `4_5` nicht); `modules` = je Spalte eine Liste (bei einer Spalte reicht eine einfache Liste). - **Module** mit Kind-Modulen (Akkordeon, Tabs, Slider, Kontaktformular, Karte, Social-Media-Follow, Icon-Liste) bekommen ihre Einträge in `items`; der Eintragstyp ergibt sich von selbst. - `label` fehlt → Admin-Label „ – “, z. B. „Hero – Button“; Zeilen „Hero – Zeile“, eine Zeile in einer Spalte „Hero – Zeile (innen)“. Abschnitten deshalb ein Label geben. - `heading` ohne `level` wird `h2` (eine Seite hat meist schon eine `h1` im Titel). Auch Module mit Titel (`blurb`, `cta`, `toggle`, Akkordeon-Eintrag, Slide, `contact-form`, `number-counter`, `team-member`) nehmen `level` (`h1`–`h6`); ohne `level` gilt Divis Standard (beim Kontaktformular `h1` – daher meist `h2` setzen). ## Kurzform-Felder | Modul | Felder | |---|---| | `text` | `content` (HTML) | | `heading` | `text`, `level` (`h1`–`h6`) | | `button` | `text`, `url`, `new_window` (true/false) | | `image` | `image_id` (Mediathek, setzt URL/ID/Alt), `src`, `alt`, `title`, `url` | | `blurb` | `title`, `url`, `content`, `image_id`, `src`, `alt`, `level` | | `cta` | `title`, `content`, `button_text`, `button_url`, `level` | | `icon` | `url`, `title` | | `divider` | `show`, `color` | | `testimonial` | `author`, `job_title`, `company`, `company_url`, `content`, `portrait_id`, `portrait_url` | | `team-member` | `name`, `position`, `content`, `image_id`, `image_url`, `level` (des Namens) | | `accordion` → `accordion-item` | Eintrag: `title`, `content`, `open`, `level` | | `tabs` → `tab` | Eintrag: `title`, `content` | | `toggle` | `title`, `content`, `open`, `level` | | `gallery` | `image_ids` (Liste von Anhang-IDs) | | `slider` → `slide` | Eintrag: `title`, `content`, `button_text`, `button_url`, `image_id`, `src`, `alt`, `level` | | `contact-form` → `contact-field` | Formular: `title`, `level`, `email`, `success_message`, `submit_text`; Feld: `title`, `id`, `type` (`input`, `email`, `text`, `checkbox`, `radio`, `select`), `required` | | `map` → `map-pin` | Karte: `address`, `lat`, `lng`, `zoom`; Pin: `title`, `content`, `address`, `lat`, `lng` | | `video` | `src`, `thumbnail` | | `number-counter` | `number`, `title`, `percent`, `level` | | `social-media-follow` → `social-media-follow-network` | Eintrag: `network` (z. B. `facebook`), `url`, `label` | | `icon-list` → `icon-list-item` | Eintrag: `text` | | `code` | `content` – nur, wenn kein natives Modul passt (Warnung) | Alle anderen Module (siehe `lit-divi-catalog`) gehen über `attrs`. Die Kurzform-Felder eines Moduls samt Pfad zeigt `lit-divi-catalog` mit `module`. Zwei Felder heißen wie Knoten-Schlüssel und lassen sich deshalb beim Einfügen **nicht** in Kurzform setzen: `type` des Kontaktformular-Felds (`type` ist dort der Modultyp) und `label` des Social-Media-Netzwerks (`label` ist dort das Admin-Label). Beim Einfügen über `attrs` (`fieldItem.advanced.type` bzw. `socialNetwork.innerContent` mit `label`) setzen, danach auch mit `lit-divi-update` über `set` (`{"set": {"type": "email"}}`). ## Presets zuweisen Presets (Namen aus `lit-divi-design-system`, Modul-Presets mit `kind: module`, Gruppen-Presets mit `kind: group`) gehen in `lit-divi-insert` (je Knoten in `nodes`), `lit-content-create` (je Knoten in `divi`) und `lit-divi-update` (je Eintrag in `changes`) in drei Feldern: - `preset` – ein Name **oder eine Liste von 1–10 Namen** (Stapel). Der Stapel wird in dieser Reihenfolge gespeichert; bei gleicher Priorität gewinnt das letzte Preset im Stapel (Divi-Verhalten). `null` entfernt das Preset. Eine leere Liste und doppelte Namen sind Fehler (`validation_failed`); wer das Preset entfernen will, sendet `null`. - `group_presets` – Objekt `{"": "" | ["", …] | null}`. Die Gruppe nennt man als Kurzname (`font-body`), mit vollem Namen (`divi/font-body`) oder als Attributpfad (`content.decoration.bodyFont`). Hat das Modul mehrere Gruppen mit demselben Namen (z. B. `spacing` für Modul und Button), ist der Kurzname ein Fehler (`validation_failed`), der die Pfade zur Auswahl nennt – dann den Attributpfad als Schlüssel verwenden. Gibt es die Gruppe am Modul nicht oder das Preset in dieser Gruppe nicht, kommt `validation_failed` mit dem Eingabepfad. `null` entfernt den Eintrag dieser Gruppe. - `clear_overrides` – `true` oder `false` (nichts anderes), siehe „Überdeckte Werte“. Gruppen-Presets und Namen kommen immer aus Divi; die Werkzeuge schreiben nie frei erfundene IDs. Einfügen mit Stapel und Gruppen-Preset: ```json { "type": "button", "text": "Termin buchen", "url": "{{link:42}}", "preset": ["CTA primär", "CTA groß"], "group_presets": { "font": "Button-Schrift" } } ``` Ändern mit `lit-divi-update` (Stapel ersetzen, Gruppen-Preset einer anderen Gruppe entfernen): ```json { "post_id": 12, "tree_rev": "…", "changes": [ { "id": "s0.r0.c1.m2", "preset": ["CTA primär"], "group_presets": { "font": "Button-Schrift", "spacing": null } } ] } ``` ### Überdeckte Werte Lokale Werte eines Moduls (`attrs`, `set`) haben Vorrang vor den Werten seiner Presets. Weist ein Aufruf ausdrücklich Presets zu (oder liegen sie schon am Modul), prüft das Werkzeug Blatt für Blatt (Pfad, Breakpoint, Zustand): weicht ein lokaler Wert von dem des Presets ab, steht in `warnings` je Preset eine Zeile wie > `s0.r0.c1.m2: lokale Werte überdecken „CTA primär“: button.decoration.background – clear_overrides: true entfernt sie.` Die Zeile nennt bis zu fünf Pfade und „und N weitere“. Das Preset wirkt dort nicht; dem Nutzer sagen und fragen, ob die lokalen Werte weg sollen. Dann denselben Knoten mit `"clear_overrides": true` ändern (z. B. `{"id": "s0.r0.c1.m2", "preset": "CTA primär", "clear_overrides": true}`): das entfernt genau die lokalen Werte, die ein ausdrücklich zugewiesenes Preset überdecken, und sonst nichts. Beim Einfügen wirkt `clear_overrides` nach `set` und `attrs` desselben Knotens, entfernt also auch Werte, die der Aufruf selbst gesetzt hat. Standard-Presets zählen nicht (Divi wendet sie implizit an, ohne dass der Knoten sie nennt). Dasselbe Preset auf vielen Seiten oder Modulen setzen: `lit/divi-presets-assign` (siehe `divi-design-system`). ## Schleifen-Inhalte Module in einem Element mit eingeschalteter Divi-Schleife zeigen Daten des jeweiligen Treffers, z. B. `{"type": "text", "content": "{{loop:post_date}}"}` mit `parent` = die Spalte (oder das Element) der Schleife. Das gilt in `lit-divi-insert` und `lit-divi-update` (`set`); außerhalb einer Schleife und in einer Schleife anderer Art lehnt das Werkzeug `loop_*`-Inhalte ab (Meldungen, Optionen und Grenzen: `divi-placeholders`, Abschnitt „Schleifen-Inhalte“). `lit-divi-move` warnt, wenn ein Modul mit Schleifen-Inhalt die Schleife verlässt. `lit-content-create` kennt keinen Schleifen-Kontext. ## Einfügen, ändern, verschieben, löschen - `lit-divi-insert`: `nodes` + Position – `parent` (Pfad-ID, z. B. Spalte `s0.r0.c1`; optional `index`), `before` oder `after`; ohne Position ans Seitenende. Oben auf der Seite sind nur Abschnitte erlaubt, in Abschnitten Zeilen, in Spalten Module. - `lit-divi-update`: `changes` = `[{"id": "s0.r0.c1.m2", "set": {"text": "Jetzt buchen"}, "preset": "CTA primär", "label": "Hero – Button"}]` – mehrere Knoten in einem Aufruf; `null` entfernt einen Wert. Neben `preset` nehmen die Einträge `group_presets` und `clear_overrides` (siehe „Presets zuweisen“). Denselben Pfad nicht zugleich über `set` und `attrs` ändern (dann zwei Änderungen senden). - `lit-divi-move`: `id` + Position (auch in andere Zeilen oder Abschnitte). - `lit-divi-delete`: `ids`, erst nach Rückfrage mit `confirm: true`. - `lit/divi-duplicate-node`: Kopie direkt hinter dem Original. - Jede Antwort enthält die neue `tree_rev` (für die nächste Änderung), `changed` mit den neuen Pfad-IDs, den betroffenen Abschnitt als `outline`, `warnings` (Qualität, siehe unten) und `revision_id`. Fehler: `validation_failed` bzw. `invalid_attr_path` mit `fields` (Eingabepfad → Problem, z. B. `nodes[0].rows[0].columns`); dann wurde nichts gespeichert. Eine unbekannte Pfad-ID meldet `lit-divi-update` mit den übrigen Eingabefehlern gesammelt als `validation_failed` (`fields.changes[i].id`), `lit-divi-move`, `lit-divi-delete` und `lit/divi-duplicate-node` als `not_found` – in beiden Fällen mit `lit-divi-outline` neu lesen. ## Spaltenbreiten ändern Die Breite einer Spalte steht in `module.decoration.sizing` (Desktop: `flexType`, z. B. `8_24` = 1/3). Wer diesen Desktop-Wert über `attrs` ersetzt, ersetzt das ganze Objekt: `flexType` immer mitschicken, sonst fällt die Breite weg. Erlaubt sind je Breakpoint (Desktop, Tablet, Telefon, …) nur die Spaltenklassen des Divi-Builders: `1_24` … `24_24`, `1_5`, `2_5`, `3_5`, `1_7`, `1_9`, `1_10`, `1_11` oder `none`. In einer Zeile mit festen Breiten alle Spalten zusammen ändern (Summe 1). Die Angabe `flexColumnStructure` der Zeile (Spaltenvorlage im Divi-Builder) passt das Werkzeug nicht an; nach einer Breitenänderung zeigt der Builder dort evtl. noch die alte Vorlage; gespeichert sind die neuen Breiten (bei Bedarf die Vorlage im Builder neu wählen). ## Sicherheit und Speichern Alle Werte werden vor dem Speichern bereinigt: Texte ohne HTML, Rich-Text ohne `unfiltered_html` nur mit dem HTML, das WordPress in Beiträgen erlaubt, Links ohne `javascript:`. `$variable`-Verweise werden geparst, geprüft und vom Plugin neu erzeugt. Eigenes HTML, CSS, HTML-Attribute, Interaktionen und die Lottie-Quelle eines Moduls (`…decoration.attributes`, `…decoration.interactions`, `…advanced.html`, `…css…`, `lottie.innerContent`) ändert nur, wer das Recht `unfiltered_html` hat – sonst „nur im Divi-Builder“ (Interaktionen können im Browser beliebige HTML-Attribute und Cookies setzen, die Lottie-Quelle lädt Animationen von fremden Adressen, die Code ausführen können). Unberührte Teile der Seite bleiben byte-identisch; Ausnahme: Divi selbst normalisiert Seiten mit eigenen HTML-/Attribut-Feldern beim Speichern – nur wenn die Seite noch nicht in Divis eigener gespeicherter Form vorliegt (z. B. importierter oder direkt in die Datenbank geschriebener Inhalt); über den Divi-Builder oder LIT MCP gespeicherte Seiten betrifft das praktisch nie (dann Warnung, dass der Inhalt beim Speichern verändert wurde – mit der neuen `tree_rev` weiterarbeiten). ## Warnungen Neue oder geänderte Knoten werden geprüft: feste Farben/Schriften, obwohl eine passende globale existiert; Bilder ohne Alt-Text; leere Module; Sprünge in der Überschriftenhierarchie; Code-Modul; lokale Werte, die ein zugewiesenes Preset überdecken (siehe „Überdeckte Werte“). Warnungen dem Nutzer nennen und möglichst gleich beheben.