03 — Installation mit DDEV
Der empfohlene Weg, und der, für den die Auslieferung gebaut ist. Was heruntergeladen wird, ist keine Extension, sondern ein vollständiges TYPO3-Projekt: entpacken, ein Skript starten, und eine lauffähige Site steht — samt Demo-Inhalten. Man beginnt bei einer fertigen Standard-Site und passt sie an, statt eine aus einem leeren Seitenbaum aufzubauen.
Die Installation im Video

Das Video wird erst von YouTube geladen, wenn Play gedrückt wird — vorher geht keine Anfrage hinaus (warum).
Was ausgeliefert wird
Auf licence.yavithemes.com anmelden, dann Konto → Downloads. Zu jeder aktiven Lizenz gehört ein ZIP, benannt nach dem Produktcode — yavi-lucerne.zip für Lucerne. Es enthält das Theme, die Core-Extension und das Projekt darum herum:
| Pfad | Was es ist |
|---|---|
.ddev/ | DDEV-Konfiguration: Projekttyp typo3, PHP 8.4, nginx-fpm, MariaDB 10.11, Docroot public/ |
composer.json | TYPO3-v14-Basisdistribution, Bootstrap Package 16, b13/container — und ./packages/* als path-Repository |
packages/yavi-core/ | die Core-Extension: Inhaltselemente, Backend-Modul, SCSS |
packages/yavi-lucerne/ | das Theme: das Design auf dem Core |
packages/yavi-lucerne/Initialisation/Site/yavilucerne/ | die Site-Konfiguration, die der Installer nach config/sites/<id>/ kopiert |
packages/yavi-lucerne/Initialisation/Files/ | die Demo-Medien, ca. 25 MB, die Bilder, auf die diese Seiten verweisen |
.tarballs/yavi-demo.sql.gz | die Demo-Datenbank — jede Seite, die die Demo-Site zeigt |
.tarballs/yavi-lucerne-demo.t3d | derselbe Inhalt als Importdatei, um die Demo in ein bestehendes TYPO3 zu ergänzen. Auf diesem Weg nicht verwendet; siehe 04 — Bestehendes TYPO3. |
.tarballs/yavi-static-elements.t3d | Topbar, Footer und die Hüllen der Rechtsseiten, ohne Demo-Inhalte. Wird verwendet, wenn ohne Demo installiert wird. |
init-static-elements.php | richtet diese Struktur ein und schreibt die Einstellungen um, die darauf zeigen |
.env, .env.local | Umgebungsvariablen für die beiden Kontexte |
init-yavi.sh | das Setup-Skript |
Ein config/sites/ gibt es im Archiv nicht. Die Site-Konfiguration reist als Vorlage im Theme mit, und der Installer kopiert sie auf den gewählten Site-Identifier. Das hält zugleich den Lizenzschlüssel aus dem Paket heraus — die mitgelieferte Vorlage trägt einen leeren.
composer.json löst packages/* als lokales path-Repository auf, die Installation läuft also ohne Zugangsdaten und ohne Netzverbindung zu uns. Für Updates gibt es ein lizenziertes Composer-Repository, das sich später einschalten lässt — siehe Updates.Voraussetzung
Ein laufendes DDEV mit Docker. DDEV selbst zu installieren und einzurichten liegt auf deiner Seite und wird hier nicht behandelt — dafür gibt es die Dokumentation von DDEV. Alles Weitere, was das Projekt braucht — Composer, PHP und die Datenbank —, läuft im Container.
Sobald ddev auf der Kommandozeile verfügbar ist, ist der Rest dieses Kapitels die vollständige Installation.
1. Entpacken und starten
Das Archiv bringt bereits einen eigenen Ordner mit; es wird also dort entpackt, wo es liegen soll:
unzip yavi-lucerne.zip
cd yavi-lucerne
chmod +x init-yavi.sh
./init-yavi.shDas Skript ist interaktiv und stellt acht Fragen:
| Abfrage | Bedeutung |
|---|---|
Choose [1/2] | 1 = .env.local, 2 = .env. Beide liegen im ZIP; passend zur Maschine wählen. |
Enter DDEV project name | Wird zu name: in .ddev/config.yaml und damit zur URL — yavilucerne → https://yavilucerne.ddev.site. |
Enter site identifier | Der Ordner unter config/sites/. Jeder Pfad in dieser Dokumentation, der config/sites/<id>/ schreibt, meint diesen Namen. |
Enter project title | Pflichtangabe, ohne Vorgabe. Wird im Backend angezeigt. |
Install the demo site …? [Y/n] | Y installiert den Seitenbaum, seine Inhalte und die Medien. n legt stattdessen eine Wurzelseite mit der Grundstruktur des Themes an — Topbar, Footer und die Rechtsseiten, aber nichts aus der Demo. Siehe Ohne die Demo installieren weiter unten. |
Enter backend username | Vorgabe admin. |
Enter backend password | Wird nicht angezeigt. |
Enter backend e-mail | Pflichtangabe. |
Die letzten drei kommen am Ende, wenn die Datenbank steht. Alles Übrige stammt aus der Umgebungsdatei, und das Skript schreibt die Antworten dorthin zurück — ein zweiter Lauf kennt sie also bereits.
Den Lizenzschlüssel vorab eintragen
Optional, spart aber einen Schritt. Der Schlüssel gehört vor dem Start in die Umgebungsdatei:
LICENCE_KEY="XXXX-XXXX-XXXX-XXXX"Der Installer schreibt ihn dann nach config/sites/<id>/settings.yaml. Bleibt er leer, sagt das Skript das und macht weiter; der Schlüssel wird danach im Backend eingetragen.
2. Was das Skript tut
Der Reihe nach — einmal lesenswert, denn zwei Schritte sind destruktiv:
- Findet DDEV. Das
bin-Verzeichnis von Homebrew landet nur über eine Login- oder interaktive Shell imPATH; ein Lauf aus einem VSCode-Task oder aus cron sähe es also nicht. Das Skript sieht selbst in/opt/homebrew/binund/usr/local/binnach. - Lädt die gewählte Umgebungsdatei.
- Schreibt den Projektnamen in
.ddev/config.yaml. Das geschieht, bevor irgendetwas gelöscht wird, dennddev deletelöst das Projekt über diese Datei auf — der mitgelieferte Name ist der, aus dem dieses Paket gebaut wurde, nicht deiner. - Löscht das bestehende DDEV-Projekt —
ddev delete --omit-snapshot -y—, aber nur beiRESET_DB=1. Die mitgelieferte.envhatRESET_DB=1. - Startet DDEV, nachdem
public/angelegt wurde. Das Verzeichnis muss vorddev startexistieren, sonst warnt DDEV vor einem falsch konfigurierten Docroot. - Schreibt
PROJECT_NAME,SITE_IDENTIFIER,PROJECT_TITLE,INSTALL_DEMOund das aufgelösteDDEV_BASEin die Umgebungsdatei zurück. ddev composer install— hier werdenpackages/yavi-coreundpackages/yavi-lucerneüber das path-Repository nachvendor/verlinkt.- Startet DDEV ein zweites Mal. DDEV schreibt
config/system/additional.php— Datenbankverbindung, ImageMagick-Pfade, Mail-Transport undtrustedHostsPattern—, aber erst, wenn es das Projekt als TYPO3 erkennt, und das erkennt es anvendor/typo3. Bei Schritt 5 gab es das noch nicht. Ohne diesen Schritt beantwortet die Site jede Anfrage mit - „The current host header value does not match the configured trusted hosts pattern“.
- Installiert TYPO3 mit
typo3 setup, sofernconfig/system/settings.phpnicht schon existiert. - Importiert
.tarballs/yavi-demo.sql.gz— nur wenn die Demo gewünscht war und nur, wenn die Tabellepagesleer ist. Eine bestehende Site wird von diesem Schritt nie überschrieben. extension:setupaktiviert beide Extensions.- Wendet
init-settings.phpan, falls das Projekt eine solche Datei mitbringt. Sie muss nachextension:setuplaufen, das die Vorgaben ausext_conf_template.txtschreibt und diese Werte sonst überschreiben würde. - Richtet
config/sites/<id>/ein — benennt die eine mitgelieferte Konfiguration auf deinen Site-Identifier um oder kopiert sie aus demInitialisation/Site/eines Pakets. Bringen mehrere Pakete eine mit, fragt das Skript nach. - Schreibt den Lizenzschlüssel aus
LICENCE_KEYnachconfig/sites/<id>/settings.yaml. Mitgelieferte Site-Konfigurationen tragen einen leeren Schlüssel, damit nie ein Schlüssel verteilt wird — siehe unten. - Richtet die Grundstruktur ein — nur bei einer Installation ohne Demo. Legt eine Wurzelseite an, importiert
.tarballs/yavi-static-elements.t3ddarunter und schreibt die fünf Einstellungen um, die diese Datensätze über ihre uid adressieren, denn der Import vergibt neue. Danach wird der Cache geleert, weil die Einstellungen erst nach dem Bau der TypoScript-Konstanten geschrieben werden. - Kopiert
additional.phpaus demInitialisation/System/eines Pakets, aber niemals über eine bestehende Datei. - Kopiert
Initialisation/Filesjedes Pakets nachpublic/fileadmin/— wiederum nur bei gewünschter Demo, da sonst nichts auf diese Dateien verweisen würde. - Löscht alle Backend-Benutzer und -Gruppen und legt danach den abgefragten Administrator an.
- Leert die Caches und gibt die URLs aus.
init-yavi.sh ist ein Installer, kein Updater. Schritt 4 löscht bei RESET_DB=1 das gesamte DDEV-Projekt samt Datenbank, und Schritt 18 führt bedingungslos DELETE FROM be_users aus — jedes Redaktionskonto ist damit weg. Niemals auf eine Site richten, in der bereits Inhalte oder Benutzer stehen.Am Ende gibt es aus, wo alles liegt:
==> Done
Frontend: https://yavilucerne.ddev.site
Backend: https://yavilucerne.ddev.site/typo3
Site ID: yavilucerne
User: admin
Demo: installed3. Was die Demo-Inhalte mitbringen
Y. Die fertige Standard-Site — 60 Seiten, jedes Inhaltselement im echten Einsatz.Ohne Demo-InhalteAntwort n. Eine Wurzelseite mit dem Rahmen des Themes: Topbar, Footer und die Rechtsseiten.Dieser Weg installiert mit Demo-Inhalten. Sie kommen in zwei Hälften, und beide werden gebraucht — die Datenbank hält die Datensätze, der Medienordner die Dateien, auf die diese Datensätze zeigen:
| Hälfte | Quelle | Schritt | Landet in |
|---|---|---|---|
| Seiten und Inhalte | .tarballs/yavi-demo.sql.gz | 10 | der Datenbank |
| Bilder, Video, Audio | packages/*/Initialisation/Files/ | 17 | public/fileadmin/ |
Das Ergebnis ist eine vollständige Standard-Site — 60 Seiten mit Navigation und Megamenü, ein Hero-Karussell und jeder Inhaltselementtyp im echten Einsatz. Zusammen mit den Theme-Einstellungen in config/sites/<id>/settings.yaml ist das das komplette Setup: Es muss nichts weiter konfiguriert werden, damit die Site wie die Demo rendert.
Die Medien liegen nach Thema sortiert unter fileadmin/dummy-media/: hero/, team/, casestudy/, services/, gallery/, header/, audio/, video/, documentation/, downloads/, dazu yavi-icons/ und yavi-logos/ als Symbol- und Platzhalter-Logo-Bibliotheken für eigene Seiten.
Der Datenbankimport ist bedingt: Schritt 10 läuft nur, wenn die Tabelle pages leer ist. Ein zweiter Lauf des Skripts überschreibt also nie bereits angelegte Inhalte.
Ohne die Demo installieren
Bei Install the demo site mit n antworten oder vor dem Lauf INSTALL_DEMO=0 in die Umgebungsdatei schreiben. Der Demo-Dump und die Demo-Medien entfallen dann — aber am Ende steht trotzdem keine leere Installation.
Das Theme rendert seinen Rahmen aus Inhaltsdatensätzen: Topbar, Stickybar und die fünf Footer-Spalten sind allesamt Inhaltselemente, keine Einstellungen. Eine Installation, die nur die Demo überspringt, zeigte deshalb eine Site ohne Kopfleiste und mit leerem Footer — und es gäbe nichts anzuklicken, um herauszufinden, warum.
Der Installer richtet deshalb einen Startpunkt ein:
==> Setting up base structure (no demo)
Created root page 'Home' (uid 1)
Imported static elements below uid 1
page.footer.pid: 4
page.stickybar: 16
page.topbar: 15
page.socialtopbar: 13
page.theme.footernavigation.navigationValue: 5| Was entsteht | Wo es liegt |
|---|---|
| Eine Wurzelseite Home | die Site-Wurzel, rootPageId zeigt darauf |
| Ordner Static Elements | unter Home, aus der Navigation ausgeblendet |
| Topbar, Stickybar, Social-Links | Seite Static-Elements darin |
| Die fünf Footer-Spalten | Seite Footer darin |
| Sechs Seiten für Impressum, Datenschutz, AGB, Lizenz, Widerruf und Cookie-Hinweis | Ordner Footer-Navigation, bereits im Footer-Menü verdrahtet |
| Eine leere Seite Contact | direkt unter Home, aus der Navigation ausgeblendet. Sie existiert, damit der Kontaktlink im Footer ein Ziel hat; entweder füllen oder den Link umhängen |
Zwölf Seiten und sechzehn Inhaltselemente insgesamt. Ihre URLs sind flach — /imprint, /privacy-policy, /contact; die Ordner, in denen sie liegen, tauchen im Pfad nicht auf.
Die sechs Rechtsseiten tragen nur Titel und Seitenkopf. Der Text wird bewusst nicht mitgeliefert: Rechtstexte gehören dem eigenen Unternehmen, nicht dem Theme-Anbieter, und plausibel klingender Blindtext ist schlimmer als eine leere Seite, die ohnehin noch gefüllt werden muss. Der Kontaktblock im Footer arbeitet genauso — er zeigt Your Company, 2978 Cedar Lane und info@example.com als Platzhalter.
Alles Weitere im Baum ist selbst zu bauen. Was die Demo gezeigt hätte — Karussells, Kartenlayouts, die Element-Galerie — gehört nicht dazu; wer es ansehen will, installiert in einem zweiten Projekt einmal mit Demo und vergleicht.
Wie die Verdrahtung den Import übersteht
Diese fünf Einstellungen adressieren Inhalte über ihre uid, und ein Import vergibt neue Nummern. Der Installer schlägt deshalb nach, was er gerade importiert hat, und schreibt die Einstellungen passend um. Deshalb steht oben page.footer.pid: 4 und nicht die 62 aus der Demo — dieselbe Struktur, andere Nummern.
Wer die Footer-Seite später verschiebt oder selbst neu baut, richtet das Theme über genau diese Einstellung auf die neue aus: Yavi Theme → Config → Footer Content Page.
Warum die Medien zweimal existieren
Schritt 17 kopiert Initialisation/Files/ flach nach public/fileadmin/ — genau dorthin, wohin die sys_file-Datensätze des Dumps zeigen (fileadmin/dummy-media/…). TYPO3 selbst kopiert denselben Ordner bei der Aktivierung der Extension zusätzlich nach fileadmin/<extension_key>/; bei Lucerne sind das ungenutzte 24 MB unter fileadmin/yavi_lucerne/. Sie zu löschen ist unbedenklich; der Vorgang ist in sys_registry vermerkt und wiederholt sich nur bei einer Neuinstallation.
4. Der Lizenzschlüssel
Vor dem Lauf in die Umgebungsdatei eintragen, dann füllt Schritt 14 ihn ein:
LICENCE_KEY="XXXX-XXXX-XXXX-XXXX"Bleibt er leer, sagt das Skript das und macht weiter; der Schlüssel wird dann im Backend unter Yavi Theme → Licence eingetragen. So oder so ist er erforderlich — ohne gültige Lizenz arbeitet die Extension nicht, siehe 11 — Lizenz.
5. Prüfen
ddev exec vendor/bin/typo3 extension:list | grep yaviyavi_core und yavi_lucerne, beide aktiv. Im Backend erscheint unterhalb von Site Management der Eintrag Yavi Theme im Modulmenü, mit fünf Seiten: Design / Colors, Layout, Custom CSS, Config, Licence.
Fehlt das Modul, ist entweder die Extension nicht aktiv oder der Backend-Benutzer kein Administrator — das Modul ist bewusst Administratoren vorbehalten.
Wenn der Lauf bei „ddev-router failed to become ready“ stehen bleibt
Failed to start yavilucerne: ddev-router failed to become ready after 60.0sDas ist DDEV, nicht das Paket. Der Router bedient alle DDEV-Projekte einer Maschine gleichzeitig und hat sechzig Sekunden Zeit, deren Routen zu laden. Bei mehreren laufenden Projekten kann er dieses Fenster verpassen — meist ist er einen Moment später fertig, aber da hat der Installer schon abgebrochen.
ddev poweroff
./init-yavi.shddev poweroff stoppt jedes Projekt und entfernt den Router-Container; er kommt also nur mit den Routen des Projekts wieder hoch, das gerade startet. Den Installer erneut laufen zu lassen ist unbedenklich: Mit RESET_DB=1 beginnt er von vorn, und an der Abbruchstelle war noch nichts installiert.
Wiederholt sich das, ist der Router selbst verklemmt:
ddev poweroff
docker rm -f ddev-router
ddev start6. Weiter
Die Site ist installiert, aber das Theme greift erst, wenn sein Set aktiv ist und die Lizenz eingetragen wurde. Weiter mit 05 — Die erste Site einrichten.
Updates
Updates kommen über dasselbe Kundenportal: **licence.yavithemes.com → Konto → Downloads**. Die Seite listet jede Lizenz mit ihrem Datum Updates until. Die Site läuft weiter, wenn dieses Datum verstreicht — ein abgelaufenes Update-Fenster blockiert neue Versionen, nicht die vorhandene Installation.
Aktualisiert wird nur yavi-core. Die Theme-Extension gehört dir: Du bearbeitest ihr SCSS, ihre Templates und ihre Einstellungen, und ein Update darf diese Arbeit nicht überschreiben. Deshalb bietet das Portal das Framework auch einzeln an, als Framework update, neben dem vollständigen Paket:
| Download | Was es ist | Wann |
|---|---|---|
Framework update — yavi-core-<version>.zip, ca. 5 MB | die Framework-Extension allein | bei jedem Update |
Full package — yavi-lucerne.zip, ca. 60 MB | Projekt, Theme, Framework, Demo | bei einer Neuinstallation |
Ist das Update-Fenster abgelaufen, bietet die Schaltfläche Framework update weiterhin die letzte Version an, die innerhalb des Fensters erschienen ist. Das vollständige Paket wird ab diesem Tag verweigert, weil es davon nur den aktuellen Build gibt.
Vorher sichern — spätestens beim Update ist die Installation nicht mehr entbehrlich, und die Datenbankmigrationen eines Updates lassen sich nicht rückgängig machen, indem man die alten Dateien zurückspielt:
ddev snapshot
ddev export-db --file=backup-$(date +%F).sql.gzEin Update ersetzt dann einen Ordner und sonst nichts:
rm -rf packages/yavi-core
unzip yavi-core-<version>.zip -d /tmp/yavi-update
cp -R /tmp/yavi-update/yavi-core packages/
ddev composer dump-autoload
ddev exec vendor/bin/typo3 extension:setup
ddev exec vendor/bin/typo3 cache:flush@import eingebunden ist, ist ein schwer zu findender Fehler.packages/yavi-lucerne bleibt, wo es ist. Wer auch die neueren Templates des Themes will — weil sie unverändert sind oder weil zusammengeführt werden soll —, nimmt diesen Ordner aus dem vollständigen Paket und vergleicht vor dem Überschreiben.
Composer die Arbeit überlassen
Dasselbe Archiv liefert auch ein lizenziertes Composer-Repository aus; das manuelle Kopieren entfällt damit. Einmalig einrichten:
ddev composer config repositories.yavi composer https://repo.yavithemes.com
ddev composer config --auth http-basic.repo.yavithemes.com licence YOUR-LICENCE-KEY
ddev composer require webagentur-yahya/yavi-core:^1.0Von da an ist ein Update ein einziger Befehl:
ddev composer update webagentur-yahya/yavi-core
ddev exec vendor/bin/typo3 extension:setup
ddev exec vendor/bin/typo3 cache:flushDrei Dinge sind dabei wissenswert:
- Der Lizenzschlüssel ist das Passwort, der Benutzername ist beliebig. Er landet in der
auth.jsonneben dercomposer.json— diese Datei gehört in die.gitignore. Auf einem Server oder in einer Pipeline stattdessen die Umgebungsvariable verwenden:COMPOSER_AUTH='{"http-basic":{"repo.yavithemes.com":{"username":"licence","password":"YOUR-LICENCE-KEY"}}}'. - Das Repository bietet ausschließlich Versionen an, die innerhalb des eigenen Update-Fensters erschienen sind. Danach findet
composer updatenichts Neues, statt fehlzuschlagen. packages/yavi-corebleibt als die Offline-Kopie im Projekt, die das ZIP mitgebracht hat. Composer nimmt das Framework jetzt ausvendor/und ignoriert diesen Ordner.
Das Theme ist bewusst nicht Teil davon. Es bleibt ein lokales path-Paket, sodass kein composer update jemals die eigenen Änderungen daran berühren kann.
init-yavi.sh nicht erneut für ein Update aufrufen. Es würde die Datenbank und jeden Backend-Benutzer löschen.
Danach immer den Cache leeren. Das kompilierte theme-<hash>.css ist über den SCSS-Inhalt geschlüsselt; ohne Flush wird weiterhin die alte Datei ausgeliefert.
Entfernen
ddev composer remove webagentur-yahya/yavi-lucerne
ddev exec vendor/bin/typo3 cache:flushDie Inhaltsdatensätze bleiben in der Datenbank. Ihre Inhaltselementtypen gibt es dann nicht mehr, das Seitenmodul zeigt sie also als unbekannte Typen an — gelöscht werden sie nicht, und eine erneute Installation bringt sie unversehrt zurück.