ThemeBuilderEdits::showing() splits the live templates that show a layout into editable ones (named under templates) and a hidden_templates count; confirm is still decided on all of them, so a layout shown only by uneditable templates still needs confirm. The live split is read once per write for the confirm check and the field warnings, and field warnings now also survive a non-confirm refusal such as the P9 backup refusal (M-12 a). replace-text passes hidden_templates on; the write schema lists it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
45 KiB
Etappe 3 – Entscheidungen der Planung (Entwurf)
Vorbereitung von Etappe 3 („Library & Theme Builder“), 2026-09-26/27. Grundlage: Spec §3, §4.3, §5, §7, §10, §12, §15; Entscheidungen Etappe 2 (D1–D12); Rulings 2b (S1–S52), Praxistest und Security-Audit 2b. Quelle: Divi 5.2.1 (wp-content/themes/Divi, style.css:4), Pfade relativ zu themes/Divi/includes/. Live geprüft nur lesend (DDEV, wp eval-file). Entwurf – noch nicht vom Controller freigegeben. Kosten, falls falsch, jeweils am Ende.
1. Verifizierte Fakten
1.1 Divi Library (et_pb_layout)
- F1: Post-Typ
et_pb_layout(ET_BUILDER_LAYOUT_POST_TYPE,builder/post/type/Layout.php:4),capability_type post,map_meta_cap,show_ui true,show_in_rest false, unterstütztrevisions(Layout.php:79). Taxonomienlayout_category,layout_tag,layout_pack,layout_type,module_width,scope,layout_location(Layout.php:83-90). Live:assign_terms=edit_posts, verwalten =manage_categories;layout_locationist lokal nicht registriert. - F2: Anlegen (Divi 4-Weg, von Divi 5 weiter benutzt):
et_pb_submit_layout()(builder/shortcode-core.php:654-734) setzt Termescope(global/not_global),layout_type(layout/section/row/module),module_width(regular/fullwidth), Kategorien/Tags und Meta_et_pb_row_layout(Zeilen),_et_pb_module_type(Module),_et_pb_excluded_global_options = "[]"(globale Module),_et_pb_built_for_post_type,_et_pb_template_type;et_pb_create_layout()(:738-800) speichert immer mitpost_status publishüberwp_insert_post(also mit kses). Im REST-/CLI-Kontext istet_pb_submit_layoutnicht geladen (live:function_exists= false; geladen nur überbuilder/shortcode-framework.php:6). - F3: Divi 5 legt Library-Einträge über die Builder-Route
POST divi/v1/divi-library/create-iteman (builder-5/server/VisualBuilder/REST/RESTRegistration.php:743-749,DiviLibraryController::create_itemDiviLibraryController.php:606-757): D4-Konvertierung, Preset-/Farb-/Variablen-Import, dannet_pb_submit_layout(:715). Recht:edit_posts+et_pb_is_allowed('divi_library')+('save_library')(:958-966). Inhalt wird vorher mitSavingUtility::prepare_content_for_dbbereinigt (:980;VisualBuilder/Saving/SavingUtility.php:230-254: ohneunfiltered_htmlwird die Seite komplett geparst und neu serialisiert). Der Versuch, danach_et_pb_use_divi_5zu setzen, liest$new_layout_meta['layout_id']aus einem JSON-String (:715-720) – auf dieses Flag ist bei Library-Einträgen kein Verlass. - F4: Library-Einträge speichern ihren Inhalt in
post_contentin einemdivi/placeholder-Wrapper (DiviLibraryController.php:2395, 2461-2466). - F5: „Global“ = Term
scope=global; Rückfall für importierte D4-Module:_et_pb_module_typeund_et_pb_excluded_global_optionsgesetzt (builder-5/server/Packages/GlobalLayout/GlobalLayout.php:34-61,GlobalLayout::is_global_layout_template()). - F6: Instanz auf einer Seite = Platzhalterblock
divi/global-layoutmit{"globalModule":"<ID>","blockName":"divi/<typ>","localAttrs":{…}}und den Kindern alsinnerBlocks(Schnappschuss). Belegt durch die D4→D5-Konvertierung (builder-5/server/Packages/Conversion/Conversion.php:1454-1479) und die Serialisierung des Builders (builder-5/visual-builder/build/serialized-post.js, Filterdivi.serializedPost.parseFlatModuleObjectIntoBlockArray.nested: alle Attribute außerglobalModule,localAttrsMap,localChildren,globalParent,blockName,globalModuleTemplatewandern nachlocalAttrs). Kinder innerhalb einer globalen Vorlage tragenglobalParent(Conversion.php:1491-1494). Modul-Metadaten:divi/global-layouthat keine Attribute (builder-5/server/_all_modules_metadata.php:18550-18557). - F7: Ausgabe per Verweis. Beim Rendern ersetzt
BlockParserjedendivi/global-layoutdurch den aktuellen Inhalt des Library-Posts (builder-5/server/FrontEnd/BlockParser/BlockParser.php:838-884;BlockParserStore::get_global_layout_content,BlockParserStore.php:1113-1330). Aus dem SchnappschusslocalAttrswerden nur die Attribute übernommen, die die Vorlage inlocalAttrsMapals „nicht synchronisiert“ führt (apply_local_attrs_filtering,BlockParserStore.php:348); die Kinder aus der Seite nur, wenn die VorlagelocalChildren: truehat (:1307-1311). Die Seitenkopie ist also ein Schnappschuss, maßgeblich ist der Library-Post. - F8: Keine Expansion bei REST-POST.
BlockParserüberspringt die Expansion beiMigrationContext, beim Speichern und bei jedem REST-Request mit POST/PUT/PATCH (BlockParser.php:827-831,_is_rest_update_request:690-701). Unsere MCP-Aufrufe sind REST-POST –lit/page-render-summary(D5,the_contentim Prozess) sieht globale Module daher nicht. - F9: Bearbeitet man eine globale Instanz im Visual Builder, speichert der Builder sofort den Library-Post über
POST divi/v1/divi-library/save(visual-builder/build/global-layouts.js;DiviLibraryController::save:1439-1447=wp_update_post(wp_slash(…)), Inhalt vorherprepare_content_for_db). Recht:edit_posts+et_pb_is_allowed('edit_global_library')(:1494-1500) – ohneedit_postauf den Eintrag. - F10: Verschachtelte globale Module sind verboten: beim Öffnen einer globalen Vorlage im Builder werden innere
divi/global-layout„entglobalisiert“ (VisualBuilder/SettingsData/SettingsDataCallbacks.php:739-743,Framework/Portability/PortabilityPost.php:3521-3605maybe_deglobalize_nested_global_modules: Platzhalter →blockNamemitlocalAttrsals Attribute,globalParententfernt). Divi selbst liestglobalModuleaus Markup per String-Scan, weilparse_blocks()damit nicht zuverlässig umgeht (PortabilityPost.php:3510,BlockParserStore.php:1137-1184,FrontEnd/Assets/DetectFeature.php:349-359). - F11: Library-REST-Routen (
RESTRegistration.php:671-775):divi-library(Liste),/item,/update-terms,/update-item,/convert-item,/split-item,/load,/create-item,/save,/upload-image,/item-location(löscht trotz Namen Posts,DiviLibraryController.php:1197-1221). Alle nonce-geschützt, nur für den Builder. - F12: Rechte im Divi-Rollen-Editor:
et_pb_is_allowed()(builder/core.php:1128-1162); Library-Admin brauchtdivi_library+save_library(builder/functions.php:340-346), globale Einträge zusätzlichedit_global_library(functions.php:366-372; im Buildercore.php:4248-4262).theme_builderundread_dynamic_content_custom_fieldssind „gefährlich“: für andere Rollen als Administrator standardmäßig aus (core.php:1138-1156), Multisite-Super-Admins immer an. Live: keine Rollen-Einstellungen gespeichert (et_pb_role_settingsleer) → Standardwerte. - F13: Live-Bestand: 0
et_pb_layout, 0et_template, 0et_theme_builder, 0 TB-Layouts, kein Inhalt mitglobalModule(Probes1.php). Echte Library-/TB-Daten fehlen vollständig.
1.2 Theme Builder
- F14: Post-Typen
et_theme_builder,et_template,et_header_layout,et_body_layout,et_footer_layout(builder/frontend-builder/theme-builder/theme-builder.php:7-23, 89-252), allecapability_type post,show_ui false,show_in_rest false; Layouts unterstützenrevisions(:184, 216, 248), Vorlagen nicht (:152). - F15: Live- und Entwurfsstand:
et_theme_builder_get_theme_builder_post_id($live)sucht den TB-Post mit Statuspublish(live) bzw.auto-draft(Entwurf des TB-Editors), ohne Meta_et_library_theme_builder(theme-builder.php:378-413). Die Vorlagen hängen als mehrfaches Meta_et_templateam TB-Post, mit Sicherung in der Optionet_tb_templates_backup_<id>während des Speicherns (:424-441;api.php:223-243). - F16: Vorlage (
et_template) = Meta_et_default,_et_enabled,_et_autogenerated_title,_et_{header,body,footer}_layout_id,_et_{…}_layout_enabled,_et_{…}_layout_global,_et_library_item_id, mehrfach_et_use_on/_et_exclude_from(theme-builder.php:471-521).override= Layout-ID ≠ 0 oder Bereich deaktiviert (:502). - F17:
et_theme_builder_store_template($tb_id, $template, $allow_default)(theme-builder.php:1463-1586):wp_die()ohneedit_others_posts(:1464-1466); neue Vorlagen sofortpublish(:1515-1521); Layout-IDs nur übernommen, wenn der passende Typ undpublish(:1486-1496); Bedingungensanitize_text_field, dedupliziert (:1565-1583). Die Funktion hängt die Vorlage nicht an den TB-Post – das macht nuret_theme_builder_api_save(api.php:223-243). - F18:
et_theme_builder_insert_layout($options)(theme-builder.php:1643-1667):wp_die()ohneedit_others_posts,wp_insert_postmitpost_status publish(kses!), Termlayout_type=layout,et_builder_enable_for_post()(setzt_et_pb_use_builder,core.php:4438-4449). - F19: Divis TB-Speichern läuft über admin-ajax (
wp_ajax_et_theme_builder_api_save,api.php:160-273:et_builder_security_check('theme_builder', 'edit_others_posts', …)), ersetzt die gesamte_et_template-Liste des TB-Posts (:233-240), trasht beim Live-Speichern den Entwurf und markiert unreferenzierte Vorlagen/Layouts mit_et_theme_builder_marked_as_unused; nach 7 Tagen werden sie gelöscht (max. 50 je Lauf,theme-builder.php:591-678). Danachet_theme_builder_clear_wp_cache('all')undET_Core_PageResource::remove_static_resources('all','all')(api.php:249-254). - F20:
api.phpwird nur beiis_admin() || wp_doing_ajax()geladen (theme-builder.php:50-61); im REST-Kontext fehlen dieet_theme_builder_api_*-Funktionen. Vorhanden (live geprüft):et_theme_builder_insert_layout,et_theme_builder_store_template,et_theme_builder_get_theme_builder_templates,et_theme_builder_get_template_settings_options,et_theme_builder_get_flat_template_settings_options,et_theme_builder_clear_wp_cache. Divi 5 hat keine eigenen TB-REST-Routen (nurThemeBuilder/Layout.php,ThemeBuilder.phpfür die Ausgabe). - F21: Bedingungs-IDs mit Trenner
:(theme-builder.php:28):singular:post_type:<pt>:all(:703-710),archive:post_type:<pt>(nurpostoderhas_archive,:724-734),singular:post_type:<pt>:id:<id>(:805-813),singular:post_type:<pt>:children:id:<id>(:822-829),homepage(:717),search,404(:1030-1039), Archiv-, Taxonomie-, Autor-, Datumsvarianten (:873-987). Jede hat einenvalidate-Callback (template-setting-validations.php:13-325);et_theme_builder_get_flat_template_settings_options()(:1143) liefert die flache Liste. - F22: Die Layouts des Theme Builders werden bei der Ausgabe live gelesen (
et_theme_builder_get_template_layouts,theme-builder.php:1295-1406); Änderungen an einem aktiven Layout sind sofort öffentlich. Divi-Module mitappearance.themeBuilderLayouts(z. B.divi/post-content,_all_modules_metadata.php:25503;fullwidth-post-content:14455) werden in anderen Bereichen nicht gerendert (Packages/ModuleLibrary/ModuleRegistration.php:509-527). - F23: Divi-Recht für TB-Layouts im Builder:
et_pb_is_allowed('theme_builder')(functions.php:2353) plus die WP-Rechte; TB-Admin-AJAX zusätzlichedit_others_posts.
1.3 Dynamic Content, Pods, Loop
- F24:
DynamicContentOptions::get_options($post_id, $context)sammelt alles über den Filterdivi_module_dynamic_content_options(builder-5/server/Packages/Module/Layout/Components/DynamicContent/DynamicContentOptions.php:85-133). Live für Seite 831: 57 Optionen, davon 34loop_*,post_meta_key(Felderbefore|after|select_meta_key|meta_key|date_format|custom_date_format|enable_html) und je Post-Typpost_link_url_<pt>mit Feldpost_id. - F25: Meta-Schlüssel-Liste: „meistgenutzte“ Meta-Schlüssel der ganzen Website plus ACF-Felder – nur mit
read_dynamic_content_custom_fieldsoder im Kontextdisplay(DynamicContentOptionPostMetaKey.php:80-140). Pods kennt Divi nicht. - F26: Ausgabe von
custom_meta_<key>: Wert überget_post_meta/ACF, Filterdivi_module_dynamic_content_resolved_custom_meta_value(DynamicContentOptionPostMetaKey.php:404), dannesc_htmlohneenable_html(:452-457). Arrays von Strings werden mit „, “ verbunden; Beziehungs-/Dateifelder ohne ACF bleiben rohe IDs. - F27: Interner Link als natives Dynamic Content:
post_link_url_<post_type>mitsettings.post_id, Ausgabeesc_url(get_permalink($id))zur Renderzeit (DynamicContentOptionCustomPostLinkUrl.php:34, 186-217) – entwurfssicher, nach dem Veröffentlichen automatisch die schöne URL. - F28: Loop Builder:
module.advanced.loop.desktop.value.{enable, queryType, …}(Packages/Module/Options/Loop/LoopUtils.php:135-145), Werte im Loop überloop_*-Optionen; die Expansion läuft nur beim Rendern (BlockParser.php:895-905).
1.4 Stand im Plugin
- F29:
ContentSchema::EXCLUDEDschließtet_pb_layout,et_theme_builder,et_templateund die drei TB-Layout-Typen aus (src/Integrations/WordPress/Schema/ContentSchema.php:19-24);PostGuard::editableliefert dafürnot_found. Die Divi-Werkzeuge erreichen Library und TB heute nicht. - F30: Opak sind Blöcke mit
globalModule,divi/global-layoutoder nicht dekodierbaren Attributen (src/Integrations/Divi/BlockTree/Parser.php:56);Block::setAttrswirft dort (Block.php:91-96). - F31: Parser-Kosten (live, 8 Divi-Posts, 28 KB, 20 Durchläufe): Parse + NodeIndex ≈ 2 ms je 100 KB Inhalt (Probe
s3.php). - F32: Divi 5.2.1 registriert keine WordPress Abilities (
grep wp_register_ability|wp_abilities_api_initim Theme: 0 Treffer) und enthält kein MCP.
2. Empfohlene Entscheidungen
- E1 – Ein Zugang für alle Divi-Posts. Die bestehenden Divi-Werkzeuge (
lit/divi-outline,-node-get,-insert,-update,-move,-delete,-duplicate-node) akzeptieren zusätzlich IDs vonet_pb_layoutundet_header/body/footer_layout(Spec §5.1). Umsetzung: eineDiviTarget-Richtlinie nebenPostGuard(Typ, Recht, Status-Regel je Typ), dieDiviPageLoaderverwendet;ContentSchema::EXCLUDEDbleibt (die Content-Tools sehen diese Typen weiter nicht). – Grund: keine zweite Werkzeugfamilie, gleiche Pipeline (D7, S39). – Kosten, falls falsch: Rechteprüfung pro Typ an einer Stelle falsch → Zugriff auf Library/TB ohne Divi-Recht; abgefangen durch eigene Tests je Typ. - E2 – Globale Module werden im Library-Post bearbeitet, nie in der Seitenkopie. Auf Seiten bleiben
divi/global-layout-Knoten opak (D3);lit/divi-node-get/-outlineliefern für sieglobal_id,block_nameund einen Hinweis „mit post_id=<global_id> bearbeiten“ (S19-Teil 2). Schreiben in den Library-Post wirkt auf alle Instanzen (F7); die Antwort nennt die betroffenen Seiten (Verwendungssuche über"globalModule":"<id>"inpost_content, wie Divi F10) und verlangt bei mehr als einer veröffentlichten Instanzconfirm: true.localAttrs/Kinder-Schnappschüsse in Seiten werden nie angefasst; das Bearbeiten nicht synchronisierter Attribute einer einzelnen Instanz ist nicht Teil von Etappe 3. – Grund: Divis Ausgabe ist per Verweis (F7), der Builder macht es genauso (F9). – Kosten: Instanz-spezifische Abweichungen nur im Builder. - E3 – Rechte (strenger als Divi, nie lockerer). Library lesen:
edit_posts+divi_library; speichern/anlegen: +save_library; einfügen aus der Library: +add_library; globalen Eintrag bearbeiten: +edit_global_libraryundedit_postauf den Eintrag (Divi prüft das nicht, F9). Theme Builder lesen und schreiben:edit_others_posts+et_pb_is_allowed('theme_builder')(F19, F23; Spec §4.5 um die Divi-Rolle ergänzt). Dynamic-Content-Meta-Liste nur mitread_dynamic_content_custom_fields(F25). Weilet_theme_builder_store_template/insert_layoutbei fehlendem Rechtwp_die()aufrufen (F17, F18), prüft das Plugin vorher selbst.et_pb_is_allowedsteckt in einem Adapter (E15). – Kosten: ein Redakteur mit WP-Rechten, aber ohne Divi-Rolle, bekommtforbidden(gewollt, wie im Builder). - E4 – Library-Einträge legt das Plugin selbst an (kein
et_pb_submit_layout, keine Builder-Route):wp_insert_postmit leerem Inhalt und Statuspublish(Divi kennt keine Library-Entwürfe, F2), Terme/Meta wie F2, danach Inhalt überDiviSaver::saveNewim kses-Fenster (D7, D11-Nachtrag), eingewickelt indivi/placeholder(F4), Flags wieDiviFlags. Ist ein Schritt fehlerhaft, wird der Entwurf endgültig gelöscht (wielit/content-create). – Grund:et_pb_submit_layoutist im REST-Kontext nicht geladen und speichert mit kses (F2); die Builder-Route braucht Nonce und importiert Presets/Farben (F3). – Kosten: Divi ändert Terme/Meta → Einträge fehlen in der Library-Ansicht; abgesichert durch Fixture-Vergleich mit echten Builder-Einträgen (E13) und Kompatibilitätsprüfung (E15). - E5 –
lit/library-insertals Kopie oder globale Instanz. Kopie: Inhalt ohnedivi/placeholder, verschachtelte globale Platzhalter entglobalisiert wie Divi (F10), eingefügt wielit/divi-insert(StructureRules, AdminLabel). Globale Instanz: das Plugin erzeugt<!-- wp:divi/global-layout {"globalModule":"<id>","blockName":"<Wurzeltyp>"} --><!-- /wp:divi/global-layout -->ohnelocalAttrs(voll synchronisiert). Prüfungen: Eintrag existiert,publish,scope=global,read_post, Wurzeltyp passt an die Zielposition, kein globales Modul in einem globalen Library-Post (F10). – Kosten: falls der Builder leerelocalAttrs/fehlendeinnerBlocksanders erwartet, sieht der Mensch im Builder evtl. eine andere Darstellung – vor dem Bau mit einer Builder-Fixture verifizieren (E13). - E6 – Werte aus gespeicherten Inhalten (Library → Seite, Seite → Seite, Seite → Library) gelten als „gespeichert, nicht vom Client“ wie bei
lit/divi-duplicate-node, werden aber beim Wechsel des Posts erneut geprüft: für Benutzer ohneunfiltered_htmlwerden Knoten mit Builder-only-Feldern (S7/S26:*.decoration.attributes,*.advanced.html,*.css.*) und Code-Modul abgelehnt („nur im Divi-Builder“). Alles andere geht unverändert durch den BlockTree (byte-identisch). – Grund: Audit M1 – der Weg über eine andere Post-ID darf die Builder-only-Sperre nicht umgehen; Autor und damit Divisbefore/after-Filterung ändern sich mit dem Ziel-Post (R2-Befund 1). – Kosten: Redakteure können admin-gebaute Abschnitte mit eigenem CSS nicht kopieren. - E7 – Theme Builder: Vorlagen und Layouts über Divis vorhandene Funktionen (
et_theme_builder_insert_layoutmit leerem Inhalt, Inhalt danach überDiviSaver::saveNew;et_theme_builder_store_template), Zuordnung zum Live-TB-Post selbst (add_post_meta($live_id, '_et_template', …), gleiche Reihenfolge wie F19 inkl. Backup-Option), danach Cache wie F19. Nie der Entwurfs-TB-Post, nieet_theme_builder_trash_draft_and_unused_posts(). Existiert ein TB-Entwurf (auto-draft, F15), wird abgelehnt mit Hinweis „Theme Builder ist in Bearbeitung – dort speichern oder verwerfen“ (sonst überschreibt ein späteres Speichern im TB-Editor die Zuordnung und die neue Vorlage wird nach 7 Tagen gelöscht, F19). Bedingungen nur auset_theme_builder_get_flat_template_settings_options()plus derenvalidate-Callback, Post-IDs mitread_post. – Kosten: Divi ändert die TB-Speicherung → Vorlage fehlt im TB-Editor; Kompatibilitätsprüfung + E2E. - E8 – Neue TB-Vorlagen werden deaktiviert angelegt (
_et_enabled=0); aktivieren ist eine explizite Aktion inlit/tb-assign(enabled: true,confirm: true, Liste der betroffenen Bedingungen). Standardvorlage (_et_default) nie über MCP. – Grund: Spec §2 Prinzip 5 (Status bleibt, Veröffentlichen explizit); TB-Posts kennen keinen Entwurf (F17, F18, F22). – Kosten: ein Aufruf mehr. Offen als Frage F-1. - E9 – Werkzeugliste Etappe 3 und Exposition. Direkt: nur
lit/library-insert(Spec §4.3) → 22 direkte Tools, unter der Warnschwelle 25 des Tools-Tabs. Indirekt:lit/library-list(mitid→ Detail; ersetztlit/library-get),lit/library-save,lit/divi-node-copy,lit/library-make-global,lit/library-find-similar,lit/divi-dynamic-sources,lit/tb-list,lit/tb-create-template,lit/tb-assign. Gruppen: Library und Theme Builder als eigene Gruppen („nur lesen“ wirkt wie bei Divi, Audit M2:lit/library-insertundlit/divi-node-copyfolgen zusätzlich dem Modus vonlit/divi-insert). Destruktiv-Hinweis:lit/library-make-global(ersetzt Knoten),lit/tb-assign(öffentliche Wirkung). – Kosten:lit/library-getaus der Spec entfällt als eigener Name (Spec §5.7 anpassen). - E10 –
lit/library-make-global: legt einen globalen Eintrag aus dem Knoten an (E4) und ersetzt den Knoten durch eine Instanz (E5), in einem Aufruf, alles oder nichts (Library-Post wird bei Fehlschlag der Seite gelöscht). „Gleichartige Vorkommen ersetzen“ nur für inhaltsgleiche Knoten (Inhalts-Fingerabdruck, E11), mit Probelauf (Standard) undconfirm: trueje Seite mittree_rev(Muster D10). Strukturgleiche Knoten mit anderen Texten werden nur gemeldet, nie ersetzt (Spec §3.3 „fast gleich“ = später). – Kosten: Kunde muss ähnliche Abschnitte vorher angleichen. - E11 –
lit/library-find-similar: zwei Fingerabdrücke je Abschnitt/Zeile: Struktur (Blocknamen und Tiefe, Spalten-flexType, Preset-IDs) und Inhalt (kanonische Attribute ohne Admin-Label, Bytes der Kinder). Suche seitenweise mitcursor, Post-Typ-Filter, höchstens 200 Posts je Aufruf, nur Posts, die der Benutzer bearbeiten darf; kein Index/Meta (F31: ≈1 s Parse für 1000 Seiten à 50 KB, Datenbanklast dominiert). Die Schreibwarnung „ähnliche Abschnitte“ (Spec §5.5, D6) vergleicht nur mit Library-Einträgen (klein) und verweist sonst auf das Tool. – Kosten: auf sehr großen Websites mehrere Aufrufe; bei Bedarf später ein Cache nachtree_rev. - E12 – Dynamic Content.
lit/divi-dynamic-sources(post_type)liefertDynamicContentOptions::get_optionsfür einen Beispiel-Post des Typs (sonst0), ohneloop_*(S36), dazu Pods-Felder des Typs ausPodsFieldSourcemit Speicherart und Eignung (Text-ähnlich ={{field:<name>}}; Beziehung/Datei = „zeigt IDs“, F26). Beim Schreiben in einen TB-Body-Layout gilt als Kontext-Post-Typ der Typ aus den Bedingungen der zugeordneten Vorlage (singular:post_type:<pt>:…); ohne Zuordnung Warnung. Loop Builder bleibt lesbar/opak (Werte unverändert), wird nicht erzeugt. – Kosten: CPT-Archive mit Pods-Feldern in Schleifen erst später. - E13 – Übernahmen aus Etappe 2: (a)
{{link:<post_id>}}→post_link_url_<post_type>mitsettings.post_id(F27), Prüfungread_post, kein Papierkorb; nur in URL-Feldern; (b)lit/guidemittopic: "all"(alle Themen in einem Aufruf, Größenlimit); (c) S19:lit/divi-design-systemmit Filter (section: colors/variables/presets/fonts,modulefür Presets) undglobal_idinnode-get; (d)lit/page-render-summarymeldet globale Platzhalter als Hinweis „globales Modul – im Auszug nicht enthalten“ (F8) und erhält für Library-/TB-IDs keinen Zugang. – Kosten: gering. - E14 – Reihenfolge und Aufteilung. 3a „Library“: Fixtures (E16) → Übernahmen E13 →
DiviTarget/Rechte (E1, E3) →lit/library-list→ Divi-Werkzeuge auf Library-Posts inkl. globaler (E2) →lit/library-save(E4) →lit/library-insert(E5) →lit/divi-node-copy(E6) →lit/divi-dynamic-sources(E12) → Guides/Promptglobale-module-vorschlagen. 3b „Theme Builder & Konsolidierung“:lit/tb-list→ TB-Layouts in den Divi-Werkzeugen (inkl.themeBuilderLayouts-Regel F22 in StructureRules) →lit/tb-create-template(E7, E8) →lit/tb-assign→lit/library-find-similar+ Warnung (E11) →lit/library-make-global(E10) → Guidetheme-builder, Promptcustom-post-type-vorlage. Abschluss jeder Teiletappe wie 2b (Review je Task, Security-Audit, Praxistest). – Kosten: find-similar/make-global kommen spät; sie hängen an stabilen Library-Grundlagen. - E15 – Divi-Zugriffe über Adapter mit Live-Kompatibilitätsprüfung (siehe Abschnitt 5): je Divi-Bereich eine Klasse (
DiviModulesundDesignSystemReadergibt es schon; neuDiviLibraryStore,DiviThemeBuilder,DiviRoles), die Funktions-/Klassen-Existenz und Signaturen prüft und bei Abweichungunsupportedstatt Fatal liefert;lit/site-statuszeigt den Befund. – Kosten: etwas mehr Code; spart Ausfälle nach Divi-Updates. - E16 – Teststrategie. (1) Unit: Platzhalter-Erkennung, Fingerabdrücke, Bedingungs-Validierung, Instanz-Markup, Entglobalisieren gegen Divis
maybe_deglobalize_nested_global_modules(gleiche Eingaben, gleiches Ergebnis). (2) Fixtures aus echten Builder-Daten: Jan-Niclas baut vor Beginn in DDEV im Visual Builder nach Checkliste globales Modul, globale Zeile mit einem nicht synchronisierten Attribut, globaler Abschnitt, normaler Library-Abschnitt, je eine Seite mit Instanzen, eine TB-Vorlage „Person“ mit Header/Body/Footer und Bedingungen; ein neues Lese-Skripttests/Integration/divi-export-library.phpexportiertpost_content, Terme, Meta und TB-Meta alsbuilder-library-*.html/builder-tb-*.json(wie D12). Roundtrip-Test läuft automatisch mit. (3) DDEV-Smokedivi-library-smoke.sh/tb-smoke.sh(mit Aufräumen). (4) Manuelle Abnahme: vom Plugin erzeugte Einträge/Instanzen/Vorlagen im Builder und TB-Editor öffnen und speichern. – Kosten: ohne Fixtures (F13) bleiben E4/E5/E7 Vermutung; daher Fixtures als erster Schritt und Bedingung für den Bau. - E17 – Sicherheit neuer Schreibwege: jeder Weg nach
post_contentvon Library- und TB-Posts geht durch Composer/AttrWriter/TreeEditor →DiviSaver(D7, S39); Titel, Terme und Meta über WordPress mit üblicher Filterung (sanitize_text_field,wp_set_object_termsmit bestehenden Term-IDs; neue Terme nur mitmanage_categories); keine Builder-Route und keinet_pb_create_layoutmit Client-Inhalt; TB-Bedingungen nur aus Divis Liste; Revision vor jeder Änderung (Library und TB-Layouts unterstützen Revisionen, F1/F14), Protokolleintrag je Post; nach Library-/TB-Änderungenremove_static_resources('all','all',true)undet_theme_builder_clear_wp_cache('all')(Spec §5.6 Schritt 5). – Kosten: Review-Pflicht wie D7.
3. Fragen an den Benutzer (nach Wichtigkeit)
- Sollen neue Theme-Builder-Vorlagen sofort wirken? Divi kennt für Vorlagen keinen Entwurf.
- (a) Deaktiviert anlegen, Aktivieren nur ausdrücklich mit
lit/tb-assignund Bestätigung. Empfehlung. - (b) Sofort aktiv, wie im TB-Editor.
- (c) Aktiv nur auf Bedingungen für einzelne IDs, alles Breitere (ganzer Post-Typ, Archiv) deaktiviert.
- (a) Deaktiviert anlegen, Aktivieren nur ausdrücklich mit
- Wie frei darf der KI-Assistent globale Module ändern? Jede Änderung wirkt sofort auf allen Seiten, auch veröffentlichten.
- (a) Erlaubt mit Rechten wie im Builder,
confirm: trueund Liste der betroffenen Seiten. Empfehlung. - (b) Nur Administratoren (
unfiltered_html/manage_options). - (c) Globale Einträge nur lesen, Änderungen nur im Builder.
- (a) Erlaubt mit Rechten wie im Builder,
- Was zuerst: Library oder Theme Builder?
- (a) 3a Library (globale Module, Einfügen, Kopieren), dann 3b Theme Builder. Empfehlung (technisch sauberere Grundlage).
- (b) Theme Builder zuerst, weil ein Kunde CPT-Vorlagen braucht (Library-Teil danach).
- Pods-Beziehungs- und Dateifelder im Theme Builder: Divi zeigt davon nur IDs.
- (a) In Etappe 3 nur Text-ähnliche Pods-Felder anbieten, andere als „nicht geeignet“ melden. Empfehlung.
- (b) Das Plugin formatiert Pods-Werte beim Rendern (Filter
divi_module_dynamic_content_resolved_custom_meta_value) – wirkt dann auf der Website, auch ohne MCP. - (c) Ganz auf später verschieben.
- Woher kommen die echten Fixtures?
- (a) Du baust sie lokal in DDEV nach Checkliste, ein Skript exportiert sie. Empfehlung.
- (b) Export von einer Kundenseite (anonymisiert).
- (c) Nur aus Divi-Code abgeleitet (riskant, F13).
4. Risiken
| Risiko | Gegenmaßnahme |
|---|---|
Keine echten Library-/TB-Daten lokal (F13); Instanz-Format (localAttrs, innerBlocks, globalModule an der Vorlagenwurzel) nur aus Code/minifiziertem JS abgeleitet |
Fixtures zuerst (E16, Frage 5), Builder-Abnahme |
Späteres Speichern im TB-Editor überschreibt unsere _et_template-Zuordnung, Vorlage wird nach 7 Tagen gelöscht (F19) |
Ablehnung bei TB-Entwurf (E7), lit/tb-list zeigt unzugeordnete Vorlagen |
| Globale Änderung wirkt sofort auf veröffentlichte Seiten | confirm, Seitenliste, Revision des Library-Posts (E2, Frage 2) |
page-render-summary sieht globale Module nicht (F8) |
Hinweis im Auszug (E13d) |
et_theme_builder_* rufen wp_die() statt Fehler zu liefern (F17, F18) |
Vorabprüfung der Rechte, Adapter (E3, E15) |
| Divi-Interna ändern sich (Library-Meta, TB-Meta, Instanz-Format); ET kündigt ein offizielles MCP an | Adapter + Kompatibilitätsprüfung (E15), Fixture-Tests je Divi-Update |
| Builder-only-Werte gelangen über Kopie in fremde Posts (Audit M1-Muster) | E6 |
Pods mit Tabellen-Speicherung: get_post_meta findet nichts |
lit/divi-dynamic-sources meldet solche Felder als ungeeignet (E12) |
| Rollen-Editor: „gefährliche“ Divi-Rechte standardmäßig nur für Administratoren | E3, klare forbidden-Meldung mit Hinweis auf Divi → Rollen-Editor |
Große Websites: find-similar lädt viel post_content |
Cursor, 200 Posts je Aufruf (E11) |
| Loop Builder / Archive nicht abgedeckt | bewusst später (E12) |
5. Schnittstellen-Einordnung
Stufen: (a) öffentliche/dokumentierte API (WordPress-Kern, dokumentierte Divi-Hooks), (b) Divis Builder-REST/AJAX (divi/v1, admin-ajax, nonce-geschützt), (c) interne PHP-Klassen/Funktionen/Meta-Konventionen, (d) selbst nachgebildete interne Formate. Empfehlung: B = behalten, W = wechseln auf offizielleren Weg, A = in Adapter mit Live-Kompatibilitätsprüfung (E15).
Zur Offizialität: Elegant Themes dokumentiert Hooks und die Modul-API (dev.elegantthemes.com, u. a. divi_module_dynamic_content_options, divi_module_dynamic_content_resolved_custom_meta_value, divi_module_dynamic_content_custom_meta_options, divi_module_library_register_module_attrs), aber keine API für externen oder KI-Zugriff. Der Divi AI Agent läuft im Builder (im Browser, AI-Wallet-Abrechnung); in den Kommentaren zur Ankündigung schreibt ET, ein „official MCP is on the way“. Divi registriert keine WordPress Abilities (F32).
5.1 Bereits genutzt (Etappe 2a/2b)
| Schnittstelle | Stelle im Plugin | Stufe | Risiko bei Divi-Updates | Empfehlung |
|---|---|---|---|---|
WordPress-Kern: wp_update_post, Revisionen, kses an/aus, Meta-API |
DiviSaver, RevisionPoint |
a | gering | B |
Block-Delimiter-Format (<!-- wp:… -->, WP_Block_Parser-Muster) |
BlockTree/Parser |
a (WP-Format) | gering | B |
Divi-Blocknamen und Attribut-JSON (module.decoration…, flexType, divi/placeholder) |
Composer, AttrWriter, ColumnWidths |
d (Schema aus c) | mittel | B – Pfade werden gegen den Live-Katalog validiert; Builder-Fixtures |
ModuleRegistration::get_all_core_modules_metadata(), get_default_attrs() |
Schema/DiviModules |
c | mittel | A (Adapter existiert; Prüfung in lit/site-status ergänzen) |
GlobalData::get_global_colors/-variables, GlobalPreset::get_data, Option et_divi |
Design/DesignSystemReader, MediaUsageFinder |
c (REST-Pendant divi/v1/global-data/* = b) |
mittel | A; kein Wechsel auf b (nonce, Builder-Kontext) |
DynamicContentOptions::get_options() |
Pages/DynamicContentMap |
c; Füllweg über dokumentierten Filter divi_module_dynamic_content_options (a); REST divi/v1/dynamic-content/options (b) |
mittel | A (Rückfall auf Standard-Map existiert) |
$variable(...)$-Syntax, gcid/gvid, Dynamic-Content-JSON |
Compose/VariableRef, Placeholders |
d | mittel | B + Prüfung gegen Divis Regex ET_THEME_BUILDER_DYNAMIC_CONTENT_REGEX_D5 (theme-builder.php:36) im Kompatibilitätstest |
Meta _et_pb_use_divi_5, _et_pb_use_builder, _et_pb_show_page_creation |
Pages/DiviFlags, PostPresenter |
d (nachgebildet aus SyncToServerController) |
mittel | B; _et_pb_use_builder könnte über et_builder_enable_for_post() (c) laufen – kein Gewinn |
ET_Core_PageResource::remove_static_resources() |
DiviSaver |
c (dokumentierter Hook et_core_page_resource_post_id_before_clear deutet auf stabile API) |
gering | B |
et_builder_enabled_for_post_type() |
ContentSchema |
c | gering | B |
ET_BUILDER_PRODUCT_VERSION |
DiviModules |
c | gering | B |
Divis wp_insert_post_data-Filter (AttributeSecurity, HtmlSecurity) als Verteidigung in der Tiefe |
Verhalten, kein Aufruf | c | mittel | B (nie entfernen, S7) |
5.2 Geplant (Etappe 3)
| Schnittstelle | Zweck | Stufe | Risiko | Empfehlung |
|---|---|---|---|---|
| Post-Typen, Taxonomien, Meta der Library (F1, F2) | Liste, Anlegen (E4) | c/d | mittel | A (DiviLibraryStore), Vergleich mit Builder-Fixtures |
GlobalLayout::is_global_layout_template() |
„global?“ | c | gering | B (Divis eigene Definition statt Term-Logik) |
divi/global-layout-Platzhalter (globalModule, blockName, localAttrs) |
Instanzen (E5, E10) | d | hoch | A + Fixtures; nur minimale Form ohne localAttrs erzeugen |
Entglobalisieren wie PortabilityPost::maybe_deglobalize_nested_global_modules |
Kopie einfügen (E5) | c | mittel | Eigene Umsetzung (d), per Test gegen Divis Methode geprüft (Aufruf direkt wäre möglich, arbeitet aber auf Strings ohne unsere Byte-Garantie) |
Builder-Routen divi/v1/divi-library/* (F11) |
– | b | mittel | nicht nutzen: Nonce, fehlende Pro-Eintrag-Rechte (F9), create-item hängt an nicht geladenem Code (F2, F3) |
et_pb_is_allowed() |
Divi-Rollen (E3) | c | gering | A (DiviRoles) |
et_theme_builder_insert_layout, et_theme_builder_store_template |
TB schreiben (E7) | c (in Spec genannt) | mittel | B über Adapter DiviThemeBuilder, Rechte vorab (wp_die) |
et_theme_builder_get_theme_builder_post_id, …_get_theme_builder_templates, …_get_template |
TB lesen | c | gering | B/A |
_et_template-Zuordnung + Backup-Option (F15, F19) |
Vorlage aktivieren | d (admin-ajax-Weg et_theme_builder_api_save = b, im REST-Kontext nicht geladen) |
mittel | A; bei Divi-Update prüfen, ob et_theme_builder_api_save die Logik ändert |
et_theme_builder_get_flat_template_settings_options() + validate-Callbacks |
Bedingungen (E7) | c | gering | B |
et_theme_builder_clear_wp_cache, remove_static_resources('all','all',true) |
Cache | c | gering | B |
DynamicContentOptions::get_options() je Post-Typ |
lit/divi-dynamic-sources |
c (Filter a) | mittel | A (vorhandener DynamicContentMap) |
post_link_url_<pt> + post_id |
{{link:ID}} (E13a) |
d (Format), Registry c | gering | B – Name über die Registry prüfen, nicht fest verdrahten |
divi_module_dynamic_content_resolved_custom_meta_value |
nur falls Frage 4 = (b) | a | gering | B (dokumentiert) |
appearance.themeBuilderLayouts aus den Modul-Metadaten |
StructureRules für TB-Bereiche | c | gering | B (aus Live-Katalog) |
Loop Builder (module.advanced.loop) |
– | d | hoch | nicht erzeugen (E12) |
| WordPress Abilities von Divi | – | – | – | gibt es nicht (F32); beobachten, ob ETs angekündigtes MCP eine offizielle Schnittstelle bringt, die c/d-Teile ersetzen kann |
Quellen der Web-Recherche: Divi AI Agent – Ankündigung, Divi Dev Docs – Filter, Divi Developers.
5. Antworten des Benutzers (2026-09-27)
- F1 Theme-Builder-Vorlagen: standardmäßig deaktiviert angelegt; Aktivieren über ein eigenes Tool (explizit).
- F2 Globale Module bearbeiten: erlaubt mit Trockenlauf (Liste der betroffenen Seiten) und
confirm, vorher Revision/Sicherung des Bibliothekseintrags. - F3 Reihenfolge: erst 3a Bibliothek, dann 3b Theme Builder.
- F4 Pods-Beziehungs-/Dateifelder: als dynamische Quelle nur textartige Felder anbieten; andere mit Hinweis auslassen.
- F5 Testdaten: selbst erzeugen („Probier es selbst“) – über Divis eigene Speicherwege (Builder-REST-Controller/Services im Prozess), als „[Fixture] …“ markiert, danach als Fixtures ins Plugin exportiert. Pods ist lokal deaktiviert; Aktivierung für 3b beim Benutzer anfragen.
6. Umsetzung Etappe 3a (Plan 2026-09-27-etappe-3a-bibliothek.md)
- E5 präzisiert durch die Builder-Fixtures: Instanzen werden wie im Visual Builder erzeugt –
localAttrs= vollständiger Schnappschuss der Wurzel-Attribute (oberste Schlüssel sortiert), Kinder mitglobalParent, ohne Kinder selbstschließend – statt der minimalen Form ohnelocalAttrs. Byte-Test gegenpage--globale-instanzen.html. - Neuer Befund 9: Bibliothekseinträge aus Divis Dialog haben
\r\nzwischen Blöcken (Formular-Upload);LibraryContent::load()vereinheitlicht das vor jeder Übernahme (undurchsichtige Blöcke bleiben unberührt). - Kopie eines normalen Eintrags mit globalen Instanzen: Instanzen bleiben verknüpft (wie Divis
/load); entglobalisiert wird nur der Inhalt globaler Einträge (Divis Schadensbegrenzung, F10).lit/library-savemitscope: "normal"übernimmt enthaltene Instanzen ebenfalls als Verweise.mode: "global"nur für globale Einträge mit genau einer Wurzel ohne globale Module (P11: nie verschachtelte Instanzen). - E6 erweitert:
StoredNodeGuardprüft neben den S7/S26-Pfaden und dem Code-Modul auch fremde Blöcke, Freitext, nicht lesbare Blöcke, kses-instabilen Rich-Text (P3) und$variable-Verweise (Ablehnung, wenncanonical()sie für das Ziel ablehnt oder ihre Einstellungen verändern würde) – Grund: R2-Befund 1 (before/after nach dem Autor des Ziel-Posts). Lesbare globale Instanzen werden geprüft (localAttrs und Schnappschuss), nicht abgelehnt (P15). Strenger als Divi; sichtbare Ablehnung. URL-Werte:url($v) === trim($v)oder relativer Link ohne Schema (P17/P18) –kontakt/,/pfad,#ankerbleiben kopierbar. - Builder-only erweitert (S7-Gate, gilt auch für Seiten):
decoration.interactions(P16 – der Effekt „Attribut“ setzt im Browser beliebige Attribute, z. B.onclick; „Cookie“ setzt Cookies) undlottie.innerContent(P19 –srclädt fremdes JSON, lottie-web wertet Ausdrücke aus). Offen für Etappe 4: Divi-Presets können beides tragen; Preset-Schreibwege brauchen dasselbe Gate. - E3 ergänzt: neue Einträge zusätzlich nur mit
publish_posts(Bibliothekseinträge sind immerpublish);scope: "global"braucht zusätzlichedit_global_library(P7). Ohne das Divi-Recht „Divi-Bibliothek“ (oder mit deaktivierter Gruppe, P9) ist jede Bibliotheks-IDnot_found, byte-gleich mit einer fehlenden ID (P12); ohneedit_postauf dem Eintragforbiddenohne Titel.lit/library-listlistet nur Einträge mitedit_postund liest höchstens 500 Zeilen je Aufruf. - E9 umgesetzt mit:
lit/divi-node-copyundlit/divi-dynamic-sourcesin der Gruppe „Divi“; die Gruppe „Divi-Bibliothek“ sperrt als Ganzes („nur lesen“/deaktiviert) auch Schreibzugriffe der Divi-Werkzeuge auf Bibliothekseinträge (ExposurePolicy::groupWritable).lit-library-insertundlit/divi-node-copyfolgen zusätzlich dem Zustand vonlit/divi-insert(M2). P13 in 3a nur dokumentiert (Guide „Rechte“, Grenze): bei deaktivierter Gruppe oder ohnedivi_librarynennen Outline/node-get/Render-Auszug einer Seite noch die ID globaler Module; der Eintrag selbst bleibtnot_found. Vollständiges Ausblenden folgt in 3b. - Antwort F2: jede Änderung eines globalen Eintrags ist zuerst ein Probelauf (auch ohne veröffentlichte
Instanzen);
lit-divi-deletenutzt dasselbeconfirm, seinconfirm_requirednennt dann ebenfalls die betroffenen Seiten. P8a: die Bestätigung wird abgelehnt, wenn der Benutzer einen Eintrag mit Statuspublish,privateoderfuture, der den Eintrag zeigt, nicht bearbeiten darf (auch TB-Layouts und andere Bibliothekseinträge); Entwürfe blockieren nicht. Der Probelauf nennt solche IDs vorab inblocked_ids(P14). Revisionen aus: abgelehnt ohneunfiltered_html(die Sicherung liefe durch kses) oder bei deaktiviertem Papierkorb (P9); scheitert das Speichern nach einer Sicherung, nennt der Fehlerbackup_id(P14). Cache-Leerung für alle Seiten und den Theme Builder. - P1:
lit/divi-replace-textspeichert normale Bibliothekseinträge überDiviWriter::commit(); globale nie (die Ziele tragen keinconfirm) – das Ergebnis nennt die betroffenen Seiten und verweist auflit-divi-updatemitconfirm. - Bibliothekseinträge bekommen keine Divi-Flags (Befund 4);
_et_pb_row_layoutwird nicht geschrieben (Befund 5). - E13a:
{{link:<ID>}}nur in URL-Feldern; Ziel muss existieren,read_postbestehen, nicht Papierkorb,auto-draftoderinheritsein – Anhänge sind damit ausgeschlossen (P10). Entwürfe und private Ziele rendert Divi für Besucher als?page_id=<ID>(nur die ID wird sichtbar, Preflight). - F4/E12:
lit/divi-dynamic-sourceslistet nur textartige Felder; Beziehungs-/Dateifelder („nur IDs“), Tabellen-Speicher und unbekannte Feldtypen (P9) stehen unteromitted; Auswahlfelder zeigen den gespeicherten Wert, nicht die Beschriftung. Der Beispiel-Post ist nur einer, den der Benutzer bearbeiten darf. - E15: Adapter
DiviRoles,DiviLibraryStore, PrüfungDiviCompatibilityinlit-site-status(problemsje Komponente). - E13d umgesetzt als Hinweis in
notes; eine eigene Expansion globaler Module im Auszug unterbleibt. - Tests: die Unit-Suite läuft mit
memory_limit512M (phpunit.xml.distundcomposer test), weil der Divi-Katalog beim Standard von 128M nicht mehr in den Speicher passt. - Server-Instructions: Zeile „Divi-Bibliothek: …“ nur bei aktiver, beschreibbarer Gruppe; MCP-Prompts gibt es
noch nicht, der Ablauf „globale Module vorschlagen“ steht im Guide
divi-library(E14).
7. Umsetzung Etappe 3b (Plan 2026-09-27-etappe-3b-theme-builder.md)
Rulings Q1–Q25: .superpowers/sdd/2026-09-27-etappe-3b-theme-builder/progress.md.
- E7 präzisiert: Layouts und neue Vorlagen über
et_theme_builder_insert_layout/et_theme_builder_store_templatemit Rechteprüfung davor undwp_die-Sperre währenddessen; Zuordnung zur Live-Liste, Bedingungen und_et_enabledals Nachbildung von Divis Meta-Schreibweise (store_template würde bei bestehenden Vorlagen auch Standard-Kennzeichen, Titel und Onboarding-Meta neu schreiben). Nach dem Anlegen Rücklesen; Abweichung = alles zurücknehmen, auch Posts, die Divi vor einem Fehler schon eingefügt hatte (Q19). - E8/Antwort F1 umgesetzt als eigenes Tool
lit/tb-activate(stattenabledinlit/tb-assign); neue Vorlagen sind immer deaktiviert. Jede andere Änderung, die Besucher sofort sähen (Bedingungen aktiver Vorlagen, Layouts aktiver Vorlagen), ist zuerst ein Probelauf und brauchtconfirm; Layouts mit der Sicherung ausVisibleEdits(Q2, Q9). Aktiv = zugeordnet und_et_enabled, unabhängig vom Post-Status (Q8). - Der Ausschalter (
lit/tb-activatemitenabled: false) geht immer: auch bei TB-Entwurf, dann mit Warnung (Q20), und bei einer aktiven Vorlage im Papierkorb (Q16). - TB-Editor: Ablehnung bei TB-Entwurf; neue Vorlagen hängen sofort an der Live-Liste;
lit/tb-listzeigt vom Theme Builder entfernte Vorlagen (detached),lit/tb-assignmitreattachordnet sie deaktiviert wieder zu (nur mit aktiven Layouts, Q8/B10). Befunde 10–12:tests/Fixtures/divi/stage3b/README.md. - E3 für den Theme Builder:
edit_others_posts,edit_theme_options(Q15) und Divis Rollen-Recht „Theme Builder“, je Vorlage/Layoutedit_post, zum Anlegen die Veröffentlichen-Rechte. Nicht bearbeitbare Vorlagen antworten wie fehlende (Q18); aktive davon nur als Anzahl in Liste und Probeläufen vonlit/tb-assign/lit/tb-activate(Q21) und der Layout-Änderungen (hidden_templates; die Rückfrage gilt trotzdem für alle aktiven Vorlagen, Q22). - Bedingungen nur aus Divis Katalog; Objekte lesbar (Begriffe:
assign_term); strenger als Divi: Autoren-Bedingungen (archive:user:id:) nur mitlist_users(Q10). - E9: eigene Gruppe „Divi Theme Builder“ (
divi-theme-builder); alle neuen Tools indirekt, 22 direkte Tools. - E10/E11 umgesetzt mit
Fingerprint(Struktur/Inhalt). „Inhaltsgleich“ heißt gleiche Bytes einschließlich Textteilen zwischen Blöcken und Inhalt von Core-Blöcken, nur Admin-Labels ausgenommen (Q25); ersetzt wird nur auf Seiten und Beiträgen (page,post), die das Konto bearbeiten darf – Theme-Builder-Layouts auch nicht als Quelle (Q24). Globale Einträge enthalten keinen Verweis auf einen Eintrag in irgendeiner Schreibweise (Q7). D10-Semantik beim Speichern mehrerer Seiten: Abbruch bei der ersten gescheiterten Seite, Fehler nennt geänderte, gescheiterte und unveränderte Seiten. - E12: Feldprüfung im Inhalt-Layout als Warnung gegen die Inhaltstypen der Vorlagen-Bedingungen, beide Feldformen (Q11).
- P13 (vollständiges Ausblenden der Bibliotheks-IDs, auch im Suchen-und-Ersetzen) und P10 (Zielregeln der
Vollform
post_link_url_*, Bibliothekseinträge und Typen ohne Divi-Linkoption wie fehlende IDs, Q14) umgesetzt. - Restrisiken: P25 (ungewöhnliche Schreibweisen globaler Verweise), dazu Divis erneutes Auswerten von Blöcken in
Shortcode-Modulen und WooCommerce-Textmodulen (dokumentiert im Guide
divi-library); das Präfilter-Orakel vonlit/divi-replace-text(Q13) und die Race-Bedingungen zwischen Prüfen und Schreiben bleiben für Etappe U. - Server-Instructions: Zeile „Divi Theme Builder: …“ nur bei aktiver, beschreibbarer Gruppe; der Ablauf
„custom-post-type-vorlage“ steht im Guide
theme-builder.