docs: Guides für Farben, Variablen, Theme-Optionen, Schriften, Snapshots und Schleifen-Inhalte

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-10-19 23:21:09 +02:00
co-authored by Claude Sonnet 5.5
parent cfc46e1c5e
commit fc35cbe9dd
7 changed files with 387 additions and 20 deletions
+137 -10
View File
@@ -7,7 +7,8 @@
Theme-Farben heißen `primary`, `secondary`, `heading`, `body` und `link`. Theme-Farben heißen `primary`, `secondary`, `heading`, `body` und `link`.
- **Globale Variablen** (`variables`): Zahlen, Texte, Bilder, Links (`gvid-…`), Platzhalter `{{var:<Name>}}`. - **Globale Variablen** (`variables`): Zahlen, Texte, Bilder, Links (`gvid-…`), Platzhalter `{{var:<Name>}}`.
- **Theme-Schriften** (`fonts`): Überschrift und Fließtext, Platzhalter `{{font:heading}}` / `{{font:body}}`. - **Theme-Schriften** (`fonts`): Überschrift und Fließtext, Platzhalter `{{font:heading}}` / `{{font:body}}`.
- **Größen** (`sizes`): Schriftgrößen, Inhaltsbreite und Spaltenabstand aus den Theme-Optionen. - **Größen** (`sizes`): Schriftgrößen, Inhaltsbreite und Spaltenabstand aus den Theme-Optionen. Alle 20
Theme-Optionen mit Standardwerten liefert `lit/divi-theme-options-get` (siehe „Theme-Optionen“).
- **Presets** (`presets`): Modul-Presets je Modul (`kind: module`, z. B. alle Button-Presets) und - **Presets** (`presets`): Modul-Presets je Modul (`kind: module`, z. B. alle Button-Presets) und
Gruppen-Presets (`kind: group`); `default: true` markiert das Standard-Preset eines Moduls. Gruppen-Presets (`kind: group`); `default: true` markiert das Standard-Preset eines Moduls.
@@ -20,8 +21,32 @@ Regeln:
1. Vor dem Gestalten einer Seite das Designsystem lesen. 1. Vor dem Gestalten einer Seite das Designsystem lesen.
2. Globale Farben, Variablen und Presets vor festen Werten verwenden; feste Farben oder Schriften nur, wenn 2. Globale Farben, Variablen und Presets vor festen Werten verwenden; feste Farben oder Schriften nur, wenn
der Nutzer es ausdrücklich möchte. der Nutzer es ausdrücklich möchte.
3. Gibt es für einen Zweck noch keine Farbe, Variable oder kein Preset, dem Nutzer vorschlagen, es im 3. Gibt es für einen Zweck noch keine Farbe, Variable oder kein Preset, dem Nutzer vorschlagen, es anzulegen
Divi-Builder anzulegen, statt feste Werte zu verteilen. (`lit/divi-colors-set`, `lit/divi-variables-set`, `lit/divi-presets-set`), statt feste Werte zu verteilen –
zuerst Probelauf, nach Rückfrage `confirm: true`.
4. Das Designsystem wirkt auf alle Seiten der Website. Werte, Schriften und Abstände nennt der Nutzer; nichts
erfinden und nie ohne seine Rückfrage bestätigen.
5. Alle Schritte eines Designwechsels (Schriften, Farben, Variablen, Theme-Optionen, Presets) beschreibt
`workflows`, Abschnitt „Corporate Design übernehmen“.
## Ablauf jeder Änderung
Presets, Farben, Variablen und Theme-Optionen (`lit/divi-presets-set`, `lit/divi-presets-delete`,
`lit/divi-colors-set`, `lit/divi-variables-set`, `lit/divi-theme-options-update`) sowie
`lit/divi-design-restore` und `lit/divi-design-detach` laufen gleich, alle über `mcp-adapter-execute-ability`:
1. Aufruf ohne `confirm` = Probelauf. Er schreibt nichts und antwortet mit `confirm_required`: `diff` (was sich
ändert), je nach Werkzeug die betroffenen Seiten und `warnings`, dazu die `design_rev`.
2. Dem Nutzer die Änderung zeigen und **erst nach seiner Antwort** denselben Aufruf mit `confirm: true` und der
`design_rev` senden (wo der Probelauf eine nennt).
3. Vor dem Schreiben legt LIT MCP einen Snapshot an; die Antwort nennt seine `snapshot_id` (siehe „Snapshots und
Wiederherstellen“).
4. Hat sich der Bestand inzwischen geändert (z. B. im Divi-Builder), kommt `rev_mismatch` – neu prüfen.
`confirm: true` ohne `design_rev` ergibt `validation_failed`; läuft gerade eine andere Änderung am selben
Bereich, kommt `conflict` – kurz warten und den Probelauf wiederholen.
Eigene Schriften hochladen (`lit/divi-fonts-upload`) hat einen eigenen Probelauf und keinen Snapshot, siehe
„Eigene Schriften hochladen“.
## Presets anlegen, ändern, löschen ## Presets anlegen, ändern, löschen
@@ -45,14 +70,10 @@ Regeln:
nutzen: der Probelauf listet diese Seiten, danach zeigen sie das Divi-Standardaussehen. Das gilt auch für nutzen: der Probelauf listet diese Seiten, danach zeigen sie das Divi-Standardaussehen. Das gilt auch für
Standard-Gruppen-Presets: gelistet werden die Seiten mit Modulen, die diese Gruppe haben, aber kein eigenes Standard-Gruppen-Presets: gelistet werden die Seiten mit Modulen, die diese Gruppe haben, aber kein eigenes
Gruppen-Preset dafür. Gruppen-Preset dafür.
- `lit/divi-design-snapshots` / `lit/divi-design-restore` – vor jeder Änderung legt LIT MCP einen Snapshot an - `lit/divi-design-snapshots` / `lit/divi-design-restore` – Snapshots listen und wiederherstellen (siehe
(je Bereich die letzten 20); wiederherstellen mit `snapshot_id`. „Snapshots und Wiederherstellen“).
Ablauf jeder Änderung: Aufruf ohne `confirm` = Probelauf (`confirm_required` mit `diff`, betroffenen Seiten und Der Ablauf (Probelauf, `confirm: true`, `design_rev`) steht oben unter „Ablauf jeder Änderung“.
`design_rev`), dem Nutzer die Änderung zeigen, dann derselbe Aufruf mit `confirm: true` und `design_rev`. Hat sich
der Bestand inzwischen geändert (z. B. im Divi-Builder), kommt `rev_mismatch` – neu prüfen. `confirm: true` ohne
`design_rev` ergibt `validation_failed`; läuft gerade eine andere Änderung, kommt `conflict` – kurz warten und den
Probelauf wiederholen.
Rechte: Presets ändern verlangt das Recht, das Design anzupassen, und in Divis Rollen-Editor den Visual Builder. Rechte: Presets ändern verlangt das Recht, das Design anzupassen, und in Divis Rollen-Editor den Visual Builder.
Konten ohne das Recht `unfiltered_html` (z. B. Redakteure) werden abgewiesen (`forbidden`), wenn vorhandene Konten ohne das Recht `unfiltered_html` (z. B. Redakteure) werden abgewiesen (`forbidden`), wenn vorhandene
@@ -130,3 +151,109 @@ Einzelne Module bekommen Presets mit `lit-divi-insert`, `lit-divi-update` und `l
enthalten; dann nennt sie den Hinweis auf `lit/divi-presets-delete` nicht. enthalten; dann nennt sie den Hinweis auf `lit/divi-presets-delete` nicht.
- Danach `lit/divi-presets-delete` aufrufen (Probelauf, `confirm`, `design_rev`); es meldet kein `in_use` mehr, - Danach `lit/divi-presets-delete` aufrufen (Probelauf, `confirm`, `design_rev`); es meldet kein `in_use` mehr,
solange niemand das Preset neu zugewiesen hat. solange niemand das Preset neu zugewiesen hat.
## Farben und Variablen anlegen und ändern
Über `mcp-adapter-execute-ability`, Ablauf wie oben, bis zu 50 Einträge je Aufruf in `items`. Farben und
Variablen werden nie gelöscht, nur deaktiviert bzw. archiviert. Angelegte Farben und Variablen lassen sich sofort
als `{{color:<Name>}}` und `{{var:<Name>}}` verwenden (`divi-placeholders`). Fehlerhafte Angaben (unbekannte ID,
vergebener oder mehrdeutiger Name – die Meldung nennt dann die IDs –, ungültiger Wert) sammelt das Werkzeug unter
`fields` als `validation_failed`; nichts wird gespeichert.
**`lit/divi-colors-set`** – je Eintrag:
- `id` nennt eine vorhandene Farbe (ID `gcid-…`, Name, Alias `primary`, `secondary`, `heading`, `body`, `link` oder
Optionsname wie `accent_color`); ohne `id` entsteht aus `label` (Name) und `color` eine neue Farbe.
- `color`: Hex (`#rgb`, `#rrggbb`, auch mit Alpha), `rgb()`/`rgba()`/`hsl()`/`hsla()`, ein Farbname (z. B. `red`)
oder der Platzhalter `{{color:<Name>}}` zusammen mit `relative`. So entstehen abgeleitete Farben, z. B.
`{"label": "Primär abgestuft", "color": "{{color:primary}}", "relative": {"lightness": 20}}`; `relative` nimmt
`hue` (−360 bis 360), `saturation`, `lightness` und `opacity` (je −100 bis 100).
- `label` benennt um, `status: inactive` deaktiviert die Farbe, `active` holt sie zurück.
- Die fünf Hauptfarben (`primary`, `secondary`, `heading`, `body`, `link`) ändern nur `color`, und nur mit einem
festen Wert (kein Platzhalter, kein `label`, `folder` oder `status`).
**`lit/divi-variables-set`** – je Eintrag:
- `id` nennt eine vorhandene Variable (ID `gvid-…` oder Name); ohne `id` entsteht aus `type` (`numbers`,
`strings`, `images`, `links` oder `fonts`), `label` und `value` eine neue. Der Typ einer Variable bleibt.
- `value` wird je Typ geprüft (Zahl, Text, Bild- oder Link-Adresse; Schrift-Variablen nur mit einem Schriftnamen,
den Divi kennt). Aktive Variablen brauchen einen Wert.
- `label` benennt um, `status: archived` archiviert, `active` holt die Variable zurück.
- Vor dem Archivieren die Verweise ersetzen: `lit/divi-design-detach` mit `variable` setzt auf Seiten und in
Presets den aktuellen Wert ein.
Der Probelauf beider Werkzeuge nennt die betroffenen Seiten und `warnings`. Die Rechte stehen unter „Rechte im
Überblick“.
## Theme-Optionen: Schriften, Größen und Layout
`lit/divi-theme-options-get` liefert je Theme-Option den gespeicherten Wert (`null` = nicht gesetzt), den
wirksamen Wert, den Divi-Standard, Typ und Bereich bzw. Auswahl und die `design_rev`; `keys` grenzt auf einzelne
Optionen ein. `lit/divi-theme-options-update` ändert sie mit `set` (`{"Schlüssel": Wert}`, Probelauf und
`confirm` wie oben); `null` setzt eine Option auf den Divi-Standard zurück. Die 20 Schlüssel:
- Schriften: `heading_font`, `body_font`, `primary_nav_font`, `secondary_nav_font` – der exakte Name einer
Schrift, die Divi kennt (Google-Schrift, Web-Safe-Schrift oder hochgeladene Schrift); bei unbekannten Namen
antwortet das Werkzeug mit `validation_failed` und bis zu fünf Vorschlägen. Stärken: `heading_font_weight`,
`body_font_weight` (100–900).
- Größen: `body_font_size` (10–32), `body_header_size` (22–72) und je eine Tablet- und Smartphone-Größe
(`tablet_body_font_size`, `phone_body_font_size`, `tablet_header_font_size`, `phone_header_font_size`); sie
erben vom nächstgrößeren Wert, solange sie nicht gesetzt sind.
- Text: `body_font_height`, `body_header_height` (Zeilenhöhe, 0,8–3), `body_header_spacing` (Buchstabenabstand,
−2 bis 10), `body_header_style` (`italic`, `uppercase` oder `underline`; Divi kennt hier nur einen Wert).
- Layout: `content_width` (960–1920), `gutter_width` (1–4), `section_padding`, `row_padding` (je 0–10).
Die Hauptfarben gehören nicht hierher, sondern in `lit/divi-colors-set`. Theme-Optionen wirken auf die gesamte
Website: den Nutzer ausdrücklich fragen. Jede Änderung legt einen Snapshot an.
## Eigene Schriften hochladen
`lit/divi-fonts-upload` lädt eine Schrift von öffentlichen Adressen in Divis hochgeladene Schriften:
- `files`: je Format eine Datei (`woff2`, `woff`, `ttf`, `otf`) als öffentliche http(s)-Adresse, höchstens 5 MB je
Datei; `name`: 1–100 Zeichen aus A–Z, a–z, 0–9, Leerzeichen, `_` und `-` (keine Umlaute), kein Name einer
Google-, Web-Safe- oder schon hochgeladenen Schrift (auch nicht in anderer Schreibweise); `weights`: `"all"`
oder eine Liste aus 100 bis 900; `generic_family`: `serif`, `sans-serif` (Standard), `monospace`, `cursive` oder
`fantasy`.
- Ablauf: Der Probelauf (ohne `confirm`) lädt die Dateien wirklich, prüft Inhalt und Format und nennt je Datei
Format, Größe und SHA-256 – installiert aber nichts. Dem Nutzer zeigen, nach seiner Antwort denselben Aufruf mit
`confirm: true`; er lädt die Dateien erneut.
- Fehler: `font_fetch_failed` (eine Adresse ist nicht erreichbar), `font_invalid` (die Datei passt nicht zum
Format, etwa ein Bild als `woff2`), `conflict` (der Name ist vergeben), `validation_failed` (Name oder Angaben
ungültig). Nichts wird gespeichert.
- Es gibt **keinen Snapshot** und keine Rücknahme per Werkzeug: Eine hochgeladene Schrift entfernt nur der
Nutzer im Divi-Builder.
- Datenschutz: Hochgeladene Schriften liefert der eigene Server aus, nicht Google. Die Lizenz der Schrift klärt der
Nutzer.
- Danach ist die Schrift ein gültiger Name für `lit/divi-theme-options-update` (z. B. `body_font`) und für
Schrift-Variablen (`lit/divi-variables-set` mit `type: fonts`).
## Snapshots und Wiederherstellen
Vor jeder Änderung an Presets, Farben, Variablen und Theme-Optionen sichert LIT MCP den Bereich (je Bereich bleiben
die letzten 20 Snapshots); die Antwort nennt die `snapshot_id`. Wäre der Bereich zu groß für eine Sicherung (über
2 MB), antwortet das Werkzeug mit `snapshot_too_large` und schreibt nichts.
- `lit/divi-design-snapshots` mit `area` (`presets`, `colors`, `variables` oder `theme_options`; Standard
`presets`) listet die Snapshots eines Bereichs, neueste zuerst, mit Zeitpunkt, Werkzeug und Protokolleintrag.
- `lit/divi-design-restore` mit `snapshot_id`: Der Probelauf zeigt den Unterschied zum aktuellen Stand (`diff`,
`design_rev`); nach Rückfrage `confirm: true`. Vorher sichert LIT MCP den aktuellen Stand selbst – auch eine
Wiederherstellung lässt sich zurücknehmen. Ist die ID unbekannt oder verdrängt, kommt `snapshot_not_found`.
- Was ein Restore macht, hängt vom Bereich ab: **Farben**, die es im Snapshot nicht gibt, entfallen. **Variablen**,
die erst nach dem Snapshot entstanden, bleiben archiviert erhalten (Divi löscht keine). **Theme-Optionen**, die
im Snapshot nicht gesetzt waren, kehren zum Divi-Standard zurück. **Presets**: Rechte-Regel `unfiltered_html`
wie oben.
- Nicht gesichert und nicht wiederherstellbar: Seiteninhalt (dort gibt es die WordPress-Revision, die
`revision_id` der Antwort) und hochgeladene Schriften.
## Rechte im Überblick
Fehlt ein Recht, antwortet das Werkzeug mit `forbidden`; die Meldung nennt das Recht, den fehlenden Divi-Rollenwert
bitte ein Administrator unter Divi → Rollen-Editor freigeben.
- Presets und Farben: `edit_theme_options` und in Divis Rollen-Editor „Visual Builder verwenden“.
- Variablen: dasselbe und der Variablen-Manager.
- Theme-Optionen: `edit_theme_options` und die Theme-Anpassung (Divis Customizer, kein Visual Builder nötig).
- Schriften hochladen: `upload_files`, `edit_theme_options` und „Eigene Schriften verwalten“.
- Snapshots listen: `edit_theme_options`; wiederherstellen: die Rechte des jeweiligen Bereichs.
- Seiten umschreiben (`lit/divi-presets-assign`, `lit/divi-design-detach`): zusätzlich `edit_post` je Seite.
+77 -3
View File
@@ -7,11 +7,12 @@ sich auch der Button.
| Platzhalter | Bedeutung | | Platzhalter | Bedeutung |
|---|---| |---|---|
| `{{color:primary}}`, `secondary`, `heading`, `body`, `link` | die fünf Theme-Farben | | `{{color:primary}}`, `secondary`, `heading`, `body`, `link` | die fünf Theme-Farben |
| `{{color:<Name>}}` | eigene globale Farbe (Name wie in `lit-divi-design-system`) | | `{{color:<Name>}}` | eigene globale Farbe (Name wie in `lit-divi-design-system`); neue Farben legt `lit/divi-colors-set` an und sie gelten sofort als Platzhalter |
| `{{var:<Name>}}` | globale Variable (Zahl, Text, Bild, Link) | | `{{var:<Name>}}` | globale Variable (Zahl, Text, Bild, Link, Schrift); neue legt `lit/divi-variables-set` an |
| `{{font:heading}}`, `{{font:body}}` | Theme-Schrift für Überschriften bzw. Fließtext | | `{{font:heading}}`, `{{font:body}}` | Theme-Schrift für Überschriften bzw. Fließtext (die Theme-Optionen `heading_font` und `body_font`, siehe `divi-design-system`) |
| `{{post:title}}`, `excerpt`, `date`, `modified`, `author`, `url`, `featured_image`, `categories`, `tags` | dynamischer Inhalt des angezeigten Beitrags | | `{{post:title}}`, `excerpt`, `date`, `modified`, `author`, `url`, `featured_image`, `categories`, `tags` | dynamischer Inhalt des angezeigten Beitrags |
| `{{field:<meta_key>}}` | dynamischer Inhalt aus einem Feld (Pods/Meta), z. B. `{{field:telefon}}` | | `{{field:<meta_key>}}` | dynamischer Inhalt aus einem Feld (Pods/Meta), z. B. `{{field:telefon}}` |
| `{{loop:<Option>}}`, z. B. `{{loop:post_date}}` | Inhalt des aktuellen Treffers einer Divi-Schleife (Option ohne `loop_`); nur in Modulen innerhalb einer Schleife, siehe „Schleifen-Inhalte“ |
| `{{link:<ID>}}` | Link auf einen anderen Eintrag (Seite, Beitrag …), z. B. `{{link:42}}` – nur in Link-Feldern; Divi setzt beim Anzeigen die aktuelle Adresse ein, also auch für Entwürfe, die erst später veröffentlicht werden | | `{{link:<ID>}}` | Link auf einen anderen Eintrag (Seite, Beitrag …), z. B. `{{link:42}}` – nur in Link-Feldern; Divi setzt beim Anzeigen die aktuelle Adresse ein, also auch für Entwürfe, die erst später veröffentlicht werden |
| `"preset": "<Name>"` oder `["<Name>", …]`, `"group_presets": {…}` | Modul-Preset bzw. Stapel und Gruppen-Presets (keine Platzhalter, sondern eigene Felder, siehe `divi-shortform`) | | `"preset": "<Name>"` oder `["<Name>", …]`, `"group_presets": {…}` | Modul-Preset bzw. Stapel und Gruppen-Presets (keine Platzhalter, sondern eigene Felder, siehe `divi-shortform`) |
@@ -49,6 +50,79 @@ Welche dynamischen Quellen und Felder es für einen Inhaltstyp gibt, liefert `li
als IDs), Tabellen-Felder und Felder unbekannten Typs stehen mit Grund unter `omitted`. Bei Auswahlfeldern als IDs), Tabellen-Felder und Felder unbekannten Typs stehen mit Grund unter `omitted`. Bei Auswahlfeldern
zeigt Divi den gespeicherten Wert, nicht die Beschriftung. zeigt Divi den gespeicherten Wert, nicht die Beschriftung.
## Schleifen-Inhalte
Ein Element mit eingeschalteter Divi-Schleife (Abschnitt, Zeile, Spalte, Gruppe oder Modul; im Divi-Builder unter
„Schleife“) wiederholt sich je Treffer der Abfrage. Module darin zeigen mit `loop_*`-Inhalten Daten des jeweiligen
Treffers, z. B. das Datum des Beitrags. LIT MCP legt keine Schleifen an und stellt ihre Abfrage nicht ein: das macht
der Nutzer im Divi-Builder. Danach setzt der KI-Assistent die Inhalte:
```json
{ "type": "text", "content": "{{loop:post_date}}" }
```
`{{loop:<Option>}}` nimmt den Namen der Option ohne `loop_` (`{{loop:post_date}}` schreibt `loop_post_date`) und steht
wie jeder Platzhalter allein im Wert. Einstellungen wie ein Datumsformat gibt es nur in der Vollform
(`$variable({…})$` mit `settings`, z. B. `"date_format": "custom", "custom_date_format": "d.m.Y"` – Divis Auswahl hat
kein deutsches Format). Welche Optionen ein Element anbietet, liefert `lit/divi-dynamic-sources` mit `post_id` und
`node` (siehe unten).
Die Art der Schleife bestimmt die Optionen:
| Schleife (Abfrage) | Optionen |
|---|---|
| Beiträge (Beitragstypen, aktuelle Seite) | `loop_post_*`, z. B. Titel, Auszug, Datum, Autor, Beitragsbild, Link, Kategorien oder Schlagwörter (`loop_post_terms`); Feld eines Beitrags: `loop_post_meta_key_manual_custom_field` |
| Terme (Taxonomien) | `loop_term_*`, z. B. Name, Beschreibung, Anzahl, Link; Feld: `loop_term_meta_key_manual_custom_field` |
| Benutzer (Rollen) | `loop_user_*`, z. B. Name, E-Mail, Avatar, Beschreibung; Feld: `loop_user_meta_key_manual_custom_field` |
| Menü | `loop_menu_*`, z. B. Text, Link, Beschreibung |
Regeln und Fehlermeldungen:
1. Der Schleifen-Kontext ergibt sich aus der Seite: das Modul selbst oder das nächste Element über ihm, dessen
Schleife eingeschaltet ist (Desktop-Einstellung „Schleife ein“). Bei verschachtelten Schleifen gilt die innerste
für alles darunter, egal welcher Art.
2. Ohne Schleife lehnt das Werkzeug jeden `loop_*`-Inhalt ab: `Schleifen-Inhalt "loop_post_date" braucht eine
Divi-Schleife in diesem Modul oder einem übergeordneten Element (Abschnitt, Zeile, Spalte, Gruppe).` Dann das
Modul in das Schleifen-Element setzen (`parent` = die Spalte bzw. das Element mit der Schleife) oder den
Nutzer bitten, die Schleife im Divi-Builder einzuschalten.
3. Passt die Option nicht zur Art der Schleife, steht in der Meldung: `… passt nicht zur Schleife dieses Elements
(Typ: Terme).` (Typ: Beiträge, Terme, Benutzer oder Menü). Eine Option der passenden Art wählen. Das ist eine
Sicherheitsgrenze, kein Schönheitsfehler: Divi liest die Feld-Optionen in einer Term-, Benutzer- oder
Menü-Schleife sonst bei dem Objekt mit derselben ID und gäbe fremde Daten aus. Nie umgehen.
4. Die Feld-Optionen (`loop_*_meta_key_manual_custom_field`) gibt es nur in der Vollform; für den Schlüssel gelten
dieselben Regeln wie bei `{{field:<meta_key>}}` (kein Schlüssel mit `_` am Anfang).
5. Vor dem Setzen lesen: `lit/divi-dynamic-sources` mit `post_type`, `post_id` und `node` (Pfad-ID des Moduls aus
`lit-divi-outline`) nennt zusätzlich die `loop_*`-Optionen, die zur Schleife dieses Knotens passen; liegt der
Knoten in keiner Schleife, kommt stattdessen der Hinweis „kein Schleifen-Kontext“. Ohne `post_id` und `node`
liefert das Werkzeug wie bisher keine Schleifen-Optionen.
6. `lit-divi-move` erlaubt das Verschieben von Schleifen-Inhalt aus der Schleife heraus oder in eine Schleife
anderer Art (Divi lässt es zu), antwortet aber mit einer Warnung: der Inhalt zeigt dort nichts oder falsche
Daten. Warnung dem Nutzer nennen, Modul zurückschieben oder den Inhalt neu setzen.
7. `lit-divi-update` warnt ebenso, wenn ein Update die Art der Schleife eines Elements ändert und darunter
unveränderte Schleifen-Inhalte stehen.
8. Ein neues Element mit eigener Schleife und Schleifen-Inhalten darunter geht nicht in einem `lit-divi-insert`-
Aufruf (die Schleife gilt erst nach dem Speichern): erst das Element mit Schleife einfügen, dann die Inhalte
mit `parent` = dieses Element.
Grenzen (bewusst nicht gelöst; dem Nutzer sagen, statt zu umgehen):
- Die Prüfung liest die Schleife aus den Attributen des Moduls und seiner Vorfahren. Eine Schleife, die nur über ein
**Preset** eingeschaltet ist, erkennt sie nicht; dann Schleifen-Inhalte abgelehnt – der Nutzer schaltet die
Schleife am Element selbst ein.
- Der Zwei-Aufruf-Weg wird nicht verhindert, nur gemeldet: Schleifen-Inhalte (z. B. ein Beitrags-Feld) in einer
Beitrags-Schleife einfügen und danach die Art der Schleife ändern oder das Modul in eine Schleife anderer Art
verschieben. Das Werkzeug antwortet nur mit einer Warnung (Divis eigener Builder erlaubt dasselbe); sie dem
Nutzer nennen und nicht ignorieren.
- **Globale Module** (`[global <ID>]`) haben keinen Schleifen-Kontext; `loop_*` dort ist abgelehnt.
- `lit-content-create` und Theme-Builder-Vorlagen kennen keinen Schleifen-Kontext: erst die Seite mit Schleife
anlegen (Nutzer im Divi-Builder), dann die Inhalte mit `lit-divi-insert` setzen.
- Beim Kopieren von Schleifen-Containern samt Inhalt (`lit/divi-node-copy`, Bibliothek) bleiben Schleifen-Inhalte
für Konten ohne `unfiltered_html` abgelehnt; ein Administrator oder der Divi-Builder erledigt das.
- Schleifen über ACF-Wiederholungsfelder (`repeater_…`) unterstützt LIT MCP nicht.
- Das Attribut `module.advanced.loop` lässt sich über `attrs` schreiben; Schleifen ein- oder auszuschalten ändert den
Kontext aller Module darunter und geschieht nur auf ausdrücklichen Wunsch. Abfrage und Anzahl gehören in den
Divi-Builder.
## `$variable`-Werte ## `$variable`-Werte
In `lit-divi-node-get` erscheinen die übersetzten Verweise als `$variable({…})$`. Diese Werte unverändert In `lit-divi-node-get` erscheinen die übersetzten Verweise als `$variable({…})$`. Diese Werte unverändert
+9
View File
@@ -125,6 +125,15 @@ 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`). 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 ## Einfügen, ändern, verschieben, löschen
- `lit-divi-insert`: `nodes` + Position – `parent` (Pfad-ID, z. B. Spalte `s0.r0.c1`; optional `index`), - `lit-divi-insert`: `nodes` + Position – `parent` (Pfad-ID, z. B. Spalte `s0.r0.c1`; optional `index`),
+17 -5
View File
@@ -13,7 +13,8 @@ des verbundenen WordPress-Benutzers.
3. **Status respektieren:** Entwürfe bleiben Entwürfe, veröffentlichte Inhalte bleiben 3. **Status respektieren:** Entwürfe bleiben Entwürfe, veröffentlichte Inhalte bleiben
veröffentlicht. Veröffentlichen nur auf ausdrücklichen Wunsch. veröffentlicht. Veröffentlichen nur auf ausdrücklichen Wunsch.
4. **Lesen vor Schreiben:** Vor Änderungen den aktuellen Stand lesen; Schreib-Tools 4. **Lesen vor Schreiben:** Vor Änderungen den aktuellen Stand lesen; Schreib-Tools
verlangen den `rev` des letzten Lesevorgangs. verlangen den `rev` des letzten Lesevorgangs, Divi-Seiten die `tree_rev`, Änderungen am Designsystem
die `design_rev` aus dem Probelauf.
## Werkzeuge ## Werkzeuge
@@ -37,7 +38,11 @@ Status (`lit/post-unpublish`, `lit/post-schedule`, `lit/post-trash`), Kopien (`l
(`lit/menu-list`, `lit/menu-get`, `lit/menu-create`, `lit/menu-set-items`, `lit/menu-assign-location`), (`lit/menu-list`, `lit/menu-get`, `lit/menu-create`, `lit/menu-set-items`, `lit/menu-assign-location`),
Einstellungen (`lit/wp-settings-get`, `lit/wp-settings-update`), Medien (`lit/media-get`, `lit/media-upload`, Einstellungen (`lit/wp-settings-get`, `lit/wp-settings-update`), Medien (`lit/media-get`, `lit/media-upload`,
`lit/media-update`, `lit/media-delete`), Divi (`lit/divi-duplicate-node`, `lit/divi-replace-text`, `lit/media-update`, `lit/media-delete`), Divi (`lit/divi-duplicate-node`, `lit/divi-replace-text`,
`lit/divi-node-copy`, `lit/divi-dynamic-sources`), Divi-Bibliothek (`lit/library-list`, `lit/library-save`, `lit/divi-node-copy`, `lit/divi-dynamic-sources`), Divi-Designsystem (Presets: `lit/divi-preset-get`,
`lit/divi-presets-set`, `lit/divi-presets-delete`, `lit/divi-presets-assign`, `lit/divi-design-detach`; Farben und
Variablen: `lit/divi-colors-set`, `lit/divi-variables-set`; Theme-Optionen: `lit/divi-theme-options-get`,
`lit/divi-theme-options-update`; Schriften: `lit/divi-fonts-upload`; Snapshots: `lit/divi-design-snapshots`,
`lit/divi-design-restore`; Ablauf: `lit-guide` topic `divi-design-system`), Divi-Bibliothek (`lit/library-list`, `lit/library-save`,
`lit/library-find-similar`, `lit/library-make-global`), Divi Theme Builder (`lit/tb-list`, `lit/library-find-similar`, `lit/library-make-global`), Divi Theme Builder (`lit/tb-list`,
`lit/tb-create-template`, `lit/tb-assign`, `lit/tb-activate`). `lit/tb-create-template`, `lit/tb-assign`, `lit/tb-activate`).
@@ -60,12 +65,19 @@ Für den Einstieg liefert `lit-guide` mit dem Thema „all“ alle Themen in ein
Bibliothekseinträgen und Theme-Builder-Layouts kommt `restore_url` hinzu (Revisionsvergleich in WordPress) – Bibliothekseinträgen und Theme-Builder-Layouts kommt `restore_url` hinzu (Revisionsvergleich in WordPress) –
`lit/revision-restore` gilt nur für Inhaltstypen. `lit/revision-restore` gilt nur für Inhaltstypen.
- Fehler: JSON mit `code` (z. B. `validation_failed`, `rev_mismatch`, `write_failed`, `partial_write`), - Fehler: JSON mit `code` (z. B. `validation_failed`, `rev_mismatch`, `write_failed`, `partial_write`),
`message`, `hint` (und ggf. `fields`). Dem `hint` folgen. `message`, `hint` (und ggf. `fields`). Dem `hint` folgen. Weitere Codes: `forbidden` (ein Recht fehlt, die
- `confirm_required`: Nutzer fragen, dann mit `confirm: true` wiederholen. Meldung nennt es), `in_use` (ein Preset oder Eintrag wird noch verwendet; `usages` nennt die Fundstellen),
`conflict` (eine andere Änderung am Designsystem läuft noch, oder der Name einer Schrift ist vergeben),
`snapshot_not_found`, `snapshot_too_large`, `font_fetch_failed` (Schriftdatei nicht ladbar) und `font_invalid`
(Datei passt nicht zum Format).
- `confirm_required`: Nutzer fragen, dann mit `confirm: true` wiederholen. Beim Designsystem enthält die Antwort
die `design_rev`, die mit `confirm: true` zurückgegeben wird; `rev_mismatch` heißt dort: der Bestand hat sich
seit dem Probelauf geändert, den Probelauf wiederholen.
## Divi-Fähigkeit nicht freigegeben ## Divi-Fähigkeit nicht freigegeben
LIT MCP gibt jede Divi-Fähigkeit einzeln frei, z. B. „Seiten lesen“, „Seiten schreiben“, „Presets schreiben“ oder LIT MCP gibt jede Divi-Fähigkeit einzeln frei, z. B. „Seiten lesen“, „Seiten schreiben“, „Presets schreiben“,
„Farben schreiben“, „Variablen schreiben“, „Theme-Optionen schreiben“, „Schriften hochladen“ oder
„Theme Builder lesen“. Nach einem Divi-Update geschieht das automatisch, wenn alle Divi-Stellen, die eine Fähigkeit „Theme Builder lesen“. Nach einem Divi-Update geschieht das automatisch, wenn alle Divi-Stellen, die eine Fähigkeit
nutzt, unverändert sind (geprüft wird die Aufrufform, nicht das Verhalten); sonst nach einer Prüfung durch einen nutzt, unverändert sind (geprüft wird die Aufrufform, nicht das Verhalten); sonst nach einer Prüfung durch einen
Administrator. Nur Werkzeuge, die eine nicht nutzbare Fähigkeit brauchen – lesende wie schreibende –, lehnen ab; alle Administrator. Nur Werkzeuge, die eine nicht nutzbare Fähigkeit brauchen – lesende wie schreibende –, lehnen ab; alle
+59 -2
View File
@@ -14,7 +14,9 @@
## Divi-Seite bauen ## Divi-Seite bauen
1. `lit-divi-design-system` lesen (Farben, Schriften, Presets) und `lit-divi-catalog` für die Module. 1. `lit-divi-design-system` lesen (Farben, Schriften, Presets) und `lit-divi-catalog` für die Module. Fehlt eine
Farbe, Variable oder ein Preset, dem Nutzer vorschlagen, sie anzulegen (`lit/divi-colors-set`,
`lit/divi-variables-set`, `lit/divi-presets-set`; Ablauf in `divi-design-system`), statt feste Werte zu setzen.
2. Seite als Entwurf mit Inhalt anlegen: `lit-content-create` mit `divi` (Abschnitte in Kurzform, siehe 2. Seite als Entwurf mit Inhalt anlegen: `lit-content-create` mit `divi` (Abschnitte in Kurzform, siehe
`divi-shortform`) – oder eine leere Seite anlegen und Abschnitte mit `lit-divi-insert` einfügen. `divi-shortform`) – oder eine leere Seite anlegen und Abschnitte mit `lit-divi-insert` einfügen.
3. Weitere Abschnitte/Module mit `lit-divi-insert`, Anpassungen mit `lit-divi-update`; immer die `tree_rev` 3. Weitere Abschnitte/Module mit `lit-divi-insert`, Anpassungen mit `lit-divi-update`; immer die `tree_rev`
@@ -44,7 +46,8 @@ vorschlagen: `lit-guide` topic `divi-library`.
## Design auf Seiten ausrollen ## Design auf Seiten ausrollen
Ein Preset soll auf vielen Seiten gelten oder ein altes Preset verschwinden (Presets anlegen: `divi-design-system`): Ein Preset soll auf vielen Seiten gelten oder ein altes Preset verschwinden (Presets anlegen: `divi-design-system`;
ein ganzes Corporate Design: „Corporate Design übernehmen“):
1. `lit-divi-design-system` lesen (Presets je Modul) und das Preset bei Bedarf mit `lit/divi-presets-set` anlegen 1. `lit-divi-design-system` lesen (Presets je Modul) und das Preset bei Bedarf mit `lit/divi-presets-set` anlegen
(Probelauf, nach Rückfrage `confirm: true` mit `design_rev`). (Probelauf, nach Rückfrage `confirm: true` mit `design_rev`).
@@ -60,6 +63,60 @@ Ein Preset soll auf vielen Seiten gelten oder ein altes Preset verschwinden (Pre
5. Stichprobe: `lit-divi-outline` einer betroffenen Seite (zeigt Preset und Gruppen-Presets je Modul) und 5. Stichprobe: `lit-divi-outline` einer betroffenen Seite (zeigt Preset und Gruppen-Presets je Modul) und
`lit-page-render-summary`; dem Nutzer die Vorschau nennen. `lit-page-render-summary`; dem Nutzer die Vorschau nennen.
## Corporate Design übernehmen
Farben, Schriften und Abstände des Corporate Designs ins Designsystem von Divi übertragen. Die Werte nennt der
Nutzer (Styleguide, Logo-Farben, Schriftdateien) – nichts erfinden. Jede Änderung: Probelauf, Rückfrage,
`confirm: true` mit `design_rev` (Ablauf: `divi-design-system`, „Ablauf jeder Änderung“); alles wirkt auf die
ganze Website.
1. Ist-Stand lesen: `lit-divi-design-system` (Farben, Variablen, Presets; bei großen Websites mit `only` und
`module` eingrenzen) und `lit/divi-theme-options-get` (Schriften, Größen, Layout). Dem Nutzer sagen, was schon
da ist, und die Quelle der neuen Werte klären.
2. Schriften: Gibt es die Schrift schon in Divi (Google-Schrift, Web-Safe-Schrift, hochgeladene)? Dann genügt der
exakte Name in Schritt 5. Sonst `lit/divi-fonts-upload` (der Probelauf lädt die Dateien und nennt Format, Größe
und SHA-256; nach Rückfrage `confirm: true`). Es gibt keinen Snapshot, entfernen kann die Schrift nur der Nutzer
im Divi-Builder; den Datenschutz-Hinweis (eigener Server statt Google) nennen.
3. Farben: `lit/divi-colors-set` – die Hauptfarben (`primary`, `secondary`, `heading`, `body`, `link`) ändern, weitere
Farben mit `label` und `color` anlegen, abgeleitete mit `{{color:<Name>}}` und `relative`. Der Probelauf nennt
betroffene Seiten und Warnungen; dem Nutzer zeigen.
4. Variablen: `lit/divi-variables-set` für Abstände, Zahlen, Texte, Bilder, Links und Schriften. Eine Variable,
die nicht mehr gebraucht wird, erst mit `lit/divi-design-detach` (`variable`) aus Seiten und Presets lösen, dann
mit `status: archived` archivieren.
5. Theme-Optionen: `lit/divi-theme-options-update` (`heading_font`, `body_font`, Größen, Zeilenhöhen,
`content_width`, `gutter_width`, Abstände; `null` = Divi-Standard). Das ändert jede Seite der Website: den Nutzer
ausdrücklich fragen.
6. Presets: `lit/divi-presets-set` (aus einem gestalteten Modul mit `from_node` oder mit `attrs` und Platzhaltern wie
`{{color:primary}}`; `make_default: true` für das Standard-Preset), kontrollieren mit `lit/divi-preset-get`.
Auf Seiten ausrollen: „Design auf Seiten ausrollen“; alte Presets mit `lit/divi-design-detach` lösen und mit
`lit/divi-presets-delete` löschen.
7. Kontrolle: eine Beispielseite mit `lit-page-render-summary` und `lit-divi-outline` prüfen; dem Nutzer
`preview_url` und `edit_url` nennen.
8. Zurücknehmen: `lit/divi-design-snapshots` (`area` = `presets`, `colors`, `variables` oder `theme_options`), dann
`lit/divi-design-restore` (Probelauf, `confirm: true`); die `snapshot_id` steht auch in jeder Änderungsantwort.
Für Seiteninhalt gibt es nur die WordPress-Revisionen, für hochgeladene Schriften kein Restore.
9. Fehler: `conflict` (andere Änderung läuft, bei Schriften: Name vergeben) – warten und den Probelauf wiederholen
bzw. anderen Namen wählen; `rev_mismatch` (Bestand inzwischen geändert) – neu lesen; `forbidden` (Recht fehlt, die
Meldung nennt es) – Administrator bitten; `in_use` (Preset wird noch verwendet) – erst `lit/divi-design-detach`;
`divi_untested`/`divi_incompatible` – siehe „Ein Divi-Werkzeug lehnt ab“.
## Inhalte einer Divi-Schleife setzen
Beispiel: Datum des Beitrags in einer Beitragsliste. Details, Optionen und Grenzen: `divi-placeholders`,
Abschnitt „Schleifen-Inhalte“.
1. Der Nutzer schaltet im Divi-Builder die Schleife an einem Element ein (Abfrage: Beiträge, Terme, Benutzer oder
Menü); LIT MCP legt Schleifen nicht an. Das Element (Pfad-ID, z. B. `s0.r1.c0`) mit dem Nutzer klären;
`lit-divi-node-get` zeigt seine Attribute (`module.advanced.loop`).
2. `lit/divi-dynamic-sources` mit `post_type`, `post_id` und `node` (Pfad-ID eines Moduls in der Schleife) nennt die
passenden `loop_*`-Optionen mit Platzhalter.
3. `lit-divi-insert` mit `parent` = das Schleifen-Element, z. B.
`{"type": "text", "content": "{{loop:post_date}}"}`; vorhandene Module mit `lit-divi-update`.
4. Lehnt das Werkzeug ab („braucht eine Divi-Schleife“ bzw. „passt nicht zur Schleife“), die Meldung ernst nehmen:
das Modul in die Schleife setzen oder eine Option der passenden Art wählen, nie die Prüfung umgehen.
5. `lit-page-render-summary` prüfen und dem Nutzer die Vorschau nennen; ohne Treffer der Abfrage bleibt der Inhalt
leer.
## Text auf vielen Seiten ersetzen ## Text auf vielen Seiten ersetzen
`lit/divi-replace-text` zuerst mit `dry_run: true` (Standard): zeigt Treffer je Seite mit `tree_rev`. Nach `lit/divi-replace-text` zuerst mit `dry_run: true` (Standard): zeigt Treffer je Seite mit `tree_rev`. Nach
+77
View File
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Guides;
use PHPUnit\Framework\TestCase;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
/**
* The loop part of the guides (Etappe 4e) says what the tools say: the refusal phrases come from the code, and every
* {{loop:<name>}} example names an option Divi 5.15.1 really registers (research 4e, table of the loop_* options).
*/
final class LoopGuideTest extends TestCase
{
/** Divi 5.15.1 option keys (without WooCommerce and ACF repeater options). */
private const DIVI_LOOP_OPTIONS = [
'loop_post_title', 'loop_post_excerpt', 'loop_post_date', 'loop_post_modified_date', 'loop_post_author',
'loop_post_author_bio', 'loop_post_author_profile_picture', 'loop_post_comment_count',
'loop_post_featured_image', 'loop_post_id', 'loop_post_link', 'loop_post_terms',
'loop_term_name', 'loop_term_description', 'loop_term_count', 'loop_term_permalink', 'loop_term_taxonomy',
'loop_term_featured_image', 'loop_user_name', 'loop_user_username', 'loop_user_email', 'loop_user_avatar',
'loop_user_description', 'loop_user_url', 'loop_menu_text', 'loop_menu_link', 'loop_menu_menu_order',
'loop_menu_attr_title', 'loop_menu_classes', 'loop_menu_xfn', 'loop_menu_description',
];
private const PHRASES = ['braucht eine Divi-Schleife', 'passt nicht zur Schleife', 'kein Schleifen-Kontext'];
private static function root(): string
{
return dirname(__DIR__, 3);
}
/** @return string Content of all guides. */
private static function guides(): string
{
$text = '';
foreach (glob(self::root() . '/docs/guides/*.md') ?: [] as $file) {
$text .= (string) file_get_contents($file) . "\n";
}
return $text;
}
public function testGuidesExplainTheLoopRefusals(): void
{
$guides = self::guides();
foreach (self::PHRASES as $phrase) {
self::assertStringContainsString($phrase, $guides, 'guides lack "' . $phrase . '"');
}
}
public function testRefusalPhrasesAreTheOnesTheCodeSays(): void
{
$code = '';
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(self::root() . '/src'));
foreach ($files as $file) {
if (str_ends_with((string) $file, '.php')) {
$code .= (string) file_get_contents((string) $file);
}
}
foreach (self::PHRASES as $phrase) {
self::assertNotFalse(mb_stripos($code, $phrase), 'no source says "' . $phrase . '"');
}
}
public function testLoopShortFormExamplesNameRealDiviOptions(): void
{
preg_match_all('/\{\{loop:([a-z0-9_]+)\}\}/', self::guides(), $examples);
self::assertNotEmpty($examples[1], 'the guides show no {{loop:…}} example');
foreach (array_unique($examples[1]) as $name) {
self::assertContains('loop_' . $name, self::DIVI_LOOP_OPTIONS, '{{loop:' . $name . '}} is no Divi option');
}
}
}
+11
View File
@@ -130,6 +130,17 @@ final class ToolNamingTest extends TestCase
self::assertSame($files, $listedTopics); self::assertSame($files, $listedTopics);
} }
/** Every indirect tool is named in the overview (the only place a client learns which `lit/` tools exist). */
public function testOverviewNamesEveryIndirectTool(): void
{
$overview = (string) file_get_contents(dirname(__DIR__, 3) . '/docs/guides/overview.md');
preg_match_all('#`lit/([a-z]+(?:-[a-z]+)*)`#', $overview, $named);
$indirect = array_keys(array_filter(self::abilities(), static fn (bool $direct): bool => ! $direct));
self::assertNotEmpty($indirect);
self::assertSame([], array_values(array_diff($indirect, $named[1])), 'indirect tools missing in overview.md');
}
public function testOverviewListsExactlyTheDirectTools(): void public function testOverviewListsExactlyTheDirectTools(): void
{ {
$overview = (string) file_get_contents(dirname(__DIR__, 3) . '/docs/guides/overview.md'); $overview = (string) file_get_contents(dirname(__DIR__, 3) . '/docs/guides/overview.md');