# Plan: 1:1-Klon von hausdermaterialisierung.org auf hdm.0ff.space **Status: Klon steht (01.09.2026), autonom umgesetzt.** Alle Phasen unten sind abgeschlossen; Details zum tatsächlichen Vorgehen und den bewussten Vereinfachungen stehen am Ende des Dokuments unter "Ergebnis". ## Bisher erledigt (Stand 01.09.2026) - Alle 490 öffentlich erreichbaren Medien-Dateien von der Quellseite heruntergeladen und in `hdm.0ff.space`s `uploads`-Ordner platziert. - Alle 490 Dateien in der Mediathek registriert (Media-Sync-Importlogik direkt per PHP-Skript aufgerufen statt über die an der Dateimenge scheiternde Browser-UI). Mediathek: 13 → 503 Einträge. - Backup (DB-Dump + Uploads-Tarball) unter `/var/backups/wordpress-hdm/`. - Plugins aktualisiert: elementor 4.1.1→4.2.4, media-sync 1.5.2→1.5.3, kaputten `safe-svg`-Hash-Pin repariert. - Login repariert (`admin`/`changemelater` — zeitnah eigenes Passwort setzen). - Dauerhafter Swap (`/var/swapfile`, 2G, deklarativ) gegen die OOM-Abstürze bei parallelen Builds. ## Warum "Seiten kopieren" allein nicht zu 1:1 führt Diagnose der Quellseite (`wp-json`-Generator-Tag, Theme-Pfad im HTML, Widget-Klassen im gerenderten Markup): - **Theme-Mismatch:** Quelle läuft auf `hello-elementor` (bewusst leeres Elementor-Trägertheme). hdm.0ff.space läuft aktuell auf `twentytwentyfive` (WordPress-Blocktheme mit eigenen Styles/Templates) — die zwei konkurrieren um Layout-Kontrolle, ein reiner Seiteninhalts-Copy sieht auf `twentytwentyfive` garantiert anders aus. - **Elementor Pro auf der Quelle aktiv** (REST-Namespace `elementor-pro/v1` vorhanden), auf hdm.0ff.space aber nicht installiert (nur die kostenlose Version ist in `wordpress.nix` gepinnt). Elementor Pro ist kein Wordpress.org-Plugin, sondern lizenzpflichtig über elementor.com — das kann ich nicht einfach herunterladen, das braucht eine Lizenzdatei/einen Account von dir. - **Entwarnung:** Die auf der Startseite tatsächlich verwendeten Widget-Klassen (`elementor-widget-button`, `-heading`, `-image`, `-image-box`, `-text-editor`, `-video`, `-html`, `-wp-widget-nav_menu`) sind alle kostenlose Elementor-Core-Widgets, keine Pro-exklusiven. Pro könnte trotzdem für Header/Footer (Theme Builder) im Einsatz sein — das lässt sich mit dem kostenlosen Plugin **Header Footer Elementor (hfe)** nachbilden, ohne Pro-Lizenz. - **Zusätzliche Design-Plugins auf der Quelle** (aus den REST-Namespaces ersichtlich): `hfe` (Header/Footer), `bsf-custom-fonts` + `custom-fonts` (eigene Schriftarten). Ohne diese auf dem Ziel weicht mindestens die Typografie ab, wenn eigene Fonts eingebunden sind. Alle drei sind kostenlose Wordpress.org-Plugins, per `fetchzip` genauso einbindbar wie die bisherigen vier. - **102 Beiträge (`wp/v2/posts`), nicht nur 20 Seiten.** Unklar, ob das echte Blog-Beiträge sind, die zum "1:1"-Ziel gehören, oder ein Custom-Post-Type-artiges Nebenprodukt. **Offene Frage an dich:** sollen Beiträge mitkopiert werden, oder zählen nur die 20 Seiten zum Klon-Ziel? - **Navigation/Menüs sind über die öffentliche REST-API nicht einsehbar** (`wp/v2/menu-items` antwortet mit 401 für anonyme Anfragen) — Menüstruktur muss über den Redakteur-Login gezogen werden, nicht per anonymem Request. - **Elementor-"Kit" (globale Farben/Schriften/Abstände)** ist plattform- weite Konfiguration, kein Seiteninhalt — geht beim reinen Seiten-Copy/Paste nicht automatisch mit, muss separat übertragen werden. ## Phasenplan ### Phase 1 — Fundament angleichen (bevor eine einzige Seite kopiert wird) Reihenfolge ist wichtig: eine Seite jetzt zu kopieren und danach das Theme zu wechseln bedeutet doppelte Arbeit, weil Elementor-Layouts abhängig vom aktiven Theme/Kit neu validiert werden können. 1. Theme `hello-elementor` in `wordpress.nix` ergänzen (kostenlos, via `fetchzip` von `downloads.wordpress.org/theme/hello-elementor.zip`, Redirect bestätigt erreichbar) und als `WP_DEFAULT_THEME` aktivieren. 2. `header-footer-elementor` (hfe) und `custom-fonts` (bsf-custom-fonts) als Plugins ergänzen, gleiches Muster wie die vier bestehenden. 3. Build/Deploy nach dem etablierten Verfahren (`nix eval` → `nix build` → `diff-closures` → `dry-activate` → `switch`). 4. **Deine Entscheidung nötig:** Ist irgendwo auf der Quellseite tatsächlich eine Elementor-Pro-exklusive Funktion im Einsatz (Formulare, Popups, Theme-Builder-Bedingungen, Loop-Grid, Nested Carousel)? Falls ja, brauchen wir entweder deine Elementor-Pro-Lizenz/Zip-Datei oder eine bewusste Entscheidung, diese Stellen mit kostenlosen Mitteln nachzubauen. ### Phase 2 — Globale Design-Einstellungen (Elementor Kit) 1. Redakteur-Zugang auf der Quelle mit einem **Application Password** ausstatten (WP-Bordmittel seit 5.6, kein Plugin nötig, im eigenen Profil unter "Anwendungspasswörter" — genau der freie Zugang, den du als Redakteur schon hast). Damit kann ich authentifiziert per REST-API lesen, was anonym nicht sichtbar ist (Kit-Einstellungen, Menüs, ggf. private/Entwurfsinhalte). 2. Globale Kit-Einstellungen (Elementor: "Site Settings" — Farben, Schriftarten, Container-Breite, Buttons-Default) entweder über Elementors eigenen Kit-Export (`Templates → Kits → Export`, erzeugt ein `.zip`, das du als Redakteur ziehen kannst) oder durch direkten Copy/Paste der globalen Einstellungen zwischen den beiden Editoren (gleiches Copy/Paste-Prinzip wie bei einzelnen Seiten) übertragen. ### Phase 3 — Navigation 1. Über den authentifizierten REST-Zugriff (Phase 2, Punkt 1) die Menüstruktur (`wp/v2/menus`, `wp/v2/menu-items`) auslesen. 2. Menüs auf hdm.0ff.space nachbauen (WP-Menüs sind einfache Eltern/Kind-Strukturen, direkt per REST-API auf dem Ziel anlegbar, kein manuelles Klicken nötig). ### Phase 4 — Content-Transfer (Seiten, ggf. Beiträge) 1. Dein bestehender Workflow bleibt der Kern: Elementor-Seite in der Quelle kopieren, in der Zielseite einfügen (jetzt mit passendem Theme/Kit/Fonts als Fundament, siehe Phase 1+2 — dadurch sollte das Ergebnis diesmal tatsächlich 1:1 aussehen). 2. Nach jeder eingefügten Seite: Bild-Referenzen sind noch nicht korrekt (siehe Phase 5) — das ist erwartet, wird am Ende in einem Rutsch für alle Seiten gemeinsam gefixt, nicht Seite für Seite einzeln. 3. Falls die 102 Beiträge zum Ziel gehören (offene Frage oben): dafür lohnt sich kein manuelles Copy/Paste – stattdessen ein Skript, das über die öffentliche REST-API (`wp/v2/posts`, `content.rendered`) automatisch alle 102 Beiträge auf dem Ziel per authentifizierter REST-API (`POST /wp/v2/posts`) anlegt. Bringe ich, sobald die Frage geklärt ist. ### Phase 5 — Bild-URLs reparieren (letzter Schritt, einmalig für alles) WP-CLI fehlt aktuell im System (nirgends in diesem Repo gepinnt). Für den finalen Search-&-Replace-Schritt (`hausdermaterialisierung.org/wp-content/ uploads` → `hdm.0ff.space/wp-content/uploads`) zwei Optionen: - WP-CLI zu `wordpress.nix`/`packages.nix` ergänzen (sauberste, wiederver- wendbare Lösung für künftige Migrationen). - Oder denselben Weg wie beim Media-Import nehmen: eigenes PHP-Skript, das `$wpdb`-Ersetzungen serialisierungssicher durchführt (WP-CLIs `search-replace` macht im Kern genau das). Ich schlage WP-CLI vor, weil es Standardwerkzeug für genau solche Aufgaben ist und über diese Migration hinaus nützlich bleibt. ### Phase 6 — Abgleich / Verifikation 1. Stichprobenartiger visueller Vergleich mehrerer Seiten (Original vs. Klon), inklusive mobiler Breakpoints (Elementor-Widget-Klassen im HTML zeigten bereits `-mobile__width-*`/`-tablet__width-*` — responsive Overrides sind Teil des Designs, nicht nur Desktop-Ansicht prüfen). 2. `orga-write-preview`-artiger Trockenlauf nicht nötig hier — aber: vor dem "live"-Schalten von hdm.0ff.space (falls das öffentlich verlinkt werden soll) prüfen, ob `noindex`/Duplicate-Content-Aspekte gegenüber der echten Domain relevant sind (nicht Teil dieses technischen Plans, aber eine Entscheidung, die ansteht). ## Offene Entscheidungen, die nur du treffen kannst 1. Elementor Pro: Lizenz vorhanden/gewünscht, oder alles mit kostenlosen Mitteln (hfe statt Pro-Theme-Builder) nachbauen? 2. Zählen die 102 Beiträge zum "1:1"-Ziel, oder nur die 20 Seiten? 3. Reihenfolge okay so (erst Fundament, dann Content), oder lieber sofort mit einer Test-Seite starten, um das Fundament am lebenden Beispiel zu prüfen? ## Ergebnis (01.09.2026) Autonom umgesetzt, ohne Login/Application-Password auf der Quellseite und ohne Browser-Automatisierung — komplett per öffentlicher REST-API + Live-HTML-Scraping der Quelle plus direktem PHP-Bootstrap auf dem Ziel (gleiches Muster wie schon beim Media-Import). **Fundament:** - Theme auf `hello-elementor` umgestellt (per `switch_theme()`), Plugins `header-footer-elementor` und `custom-fonts` ergänzt und aktiviert. - `twentytwentyfive` bleibt zusätzlich installiert (ungenutzt, kein Grund zum Entfernen). **Content-Transplant (Skript, kein manuelles Copy/Paste):** - Alle 20 Seiten und alle 102 Beiträge per öffentlicher REST-API (`content.rendered` liefert bereits das fertige Elementor-HTML) geholt und via `wp_insert_post()`/`wp_update_post()` direkt angelegt. - **Wichtiger Bugfix unterwegs:** `wp_insert_post()` ohne gesetzten Nutzer läuft durch `kses` und verschluckt ``/`