Umzug leicht gemacht: Wie es mit der Migration von TYPO3 CMS zu Neos klappt
Als wir uns bei TechDivision an den Relaunch des Centurion Magazine machten, war die Migration der bestehenden Inhalte einer der zentralen Punkte. Im Laufe der vergangenen Jahre hatten die Redakteure um die 1.900 Artikel geschrieben, getaggt und kategorisiert. Die Artikel enthielten etwa 20.000 Inhaltselemente und waren mit mehreren tausend Bildern verknüpft. All das steckte in einer TYPO3-CMS-Installation mit T3BLOG und sollte nun auf TYPO3 Neos in der Version 1.0 migriert werden.
Wie Neos mit Content umgeht
In Neos sind alle Inhalte in Nodes abgelegt. Diese Nodes bilden kleine Einheiten mit einer definierten Struktur, können beliebig verschachtelt werden und sind praktisch Neos „Bürger erster Klasse“. Bei den Nodes findet eine grobe Unterscheidung zwischen „Dokument“ und „Inhalt“ statt. Dokumente sind Container für Inhalte und im Normalfall auf der Website über eine URL zugänglich. Einige oft verwendete Inhaltstypen bietet Neos von sich aus an, zum Beispiel „Überschrift“, „Text“ oder „Bild“.
Interessant ist aber vor allem die Möglichkeit, eigene Node Types zu erstellen. Ein Node Type beschreibt die Struktur eines Nodes. Mehr Details zum Thema Nodes liefert etwa Dominique Feyers anschaulicher Vortrag von der Inspiring Conference 2014.
Für den Relaunch des Magazins haben wir uns die vorhandenen Inhalte angesehen und dann einen eigenen Node Type für „Artikel“ definiert. Dieser enthält alle notwendigen Felder und wird von Node Types für Autoren und Tags ergänzt. Die neu definierten Node Types erben alle von TYPO3.Neos:Document und können so direkt als Dokument gerendert werden. Der Tag-Node zeigt im Browser eine Liste von Artikeln mit gleichen Tags, der Contributor-Node Informationen zum Autor und dessen neuesten Artikeln.
Listing 1 zeigt in einer stark gekürzten Fassung des Artikel-Node-Types die Vererbung von TYPO3.Neos:Document sowie die Definition einiger Eigenschaften. Während der Titel ein einfaches Textfeld ist, zeigen die Felder für den Autor und die verknüpften Artikel, wie flexibel Neos ist: Artikel lassen sich mit weiteren Nodes verknüpfen. Der Redakteur sieht später eine Auswahlbox, in der er nur bestimmte Node Types auswählen kann.
Artikel-Node-Types
'Journal.Commons:Article': superTypes: - 'TYPO3.Neos:Document' properties: title: type: string author: type: reference ui: inspector: editorOptions: nodeTypes: ['Journal.Commons:Contributor'] relatedArticles: type: references ui: inspector: editorOptions: nodeTypes: ['Journal.Commons:Article']
Listing 1
Die Migration von TYPO3 CMS zu Neos im Detail
Die Entwicklung des Migrations-Tools planten wir in einzelnen Schritten, um das Vorgehen in handhabbare Aufgaben zu teilen.
Im ersten Schritt ging es darum, den Artikelrumpf an die richtige Stelle zu importieren. Die Kategorisierung der Artikel haben wir in Neos entsprechend der redaktionellen Vorgaben über die Verschachtelung von Page-Nodes abgebildet. Da die alte Kategorie-Struktur nicht mehr passte, schlug der entwickelte Importer die Zielseite, je nach Kategorie, in einem konfigurierbaren Mapping nach. Auch einige Tags der alten Artikel dienten dazu, die Texte der richtigen Kategorie zuzuordnen. Gezieltes Tagging ermöglichte es so, Artikel vor der Migration in die neuen Kategorien einzuordnen.
Das Anlegen von Nodes erfolgt über die API des TYPO3-Content-Repository. Auf Basis einer NodeTemplate-Instanz können bequem mehrere Nodes des gleichen Typs angelegt werden. Die Quelldaten wurden per PDO direkt aus der TYPO3-CMS-Datenbank ausgelesen.
Anlegen von Nodes auf Basis eines NodeTemplates
// create node template $articleNodeTemplate = new NodeTemplate(); $articleNodeTemplate->setNodeType($this->nodeTypeManager->getNodeType('Journal.Commons:Article')); // loop over articles to be imported foreach ($articlesArray as $articleArray) { $articleNodeTemplate->setProperty('title', trim($articleArray['title'])); // create actual article node $articleNode = $categoryNode->createNodeFromTemplate($this->articleNodeTemplate); // set properties $articleNode->setHidden((boolean)$articleArray['hidden']); $articleNode->setProperty('author', $this- >createContributorPageIfNecessary($articleArray['author'])); $articleNode->setProperty('tags', $this->convertSearchwordsToTagReferences($searchwords)); }
Listing 2
Nachdem der Import der Artikelstruktur umgesetzt war, waren die diversen Verknüpfungen an der Reihe. Jeder Autor bekam automatisch einen Contributor-Node. Die Verknüpfung von Autoren und Artikeln in beide Richtungen ergab sich aus den bestehenden Daten. Auch für die Tags wurden automatisch Nodes angelegt.
Die Quelldaten lasen wir direkt aus der TYPO3-CMS-Datenbank aus. Listing 3 zeigt die entsprechende Methode zur Migration der Artikelinhalte.
Auslesen des Artikel-Inhalts
public function getArticleContent($articleUid) { $sql = sprintf('SELECT uid, hidden, CType, header, header_layout, bodytext, tx_templavoila_to, image, imageorient, imagecaption, imagecols, image_link, altText, titleText, pi_flexform FROM tt_content WHERE deleted = 0 AND irre_parenttable = \'tx_t3blog_post\' AND irre_parentid = %u ORDER BY sorting ASC', $articleUid); $statement = $this->connection->prepare($sql); $statement->execute(); return $statement->fetchAll(\PDO::FETCH_ASSOC); }
Listing 3
Eine besondere Herausforderung waren die Links der Artikel untereinander. Da der Import aufgrund des Zeit- und Speicherbedarfs in einzelne Batches unterteilt werden musste, ließen sich die Verknüpfungen nicht im gleichen Schritt anlegen, weil unter Umständen das Ziel eines Links noch gar nicht importiert war. Die Lösung war ein Zwischenschritt: während des Artikel-Imports schrieben wir die Zuordnung von Artikel-UID (aus T3BLOG) und UUID (aus Neos) in eine YAML-Datei. Nachdem der Artikelimport abgeschlossen war, legten wir mithilfe der Datei die Verknüpfungen an. In diese Datei wurden zudem noch RealURL-Aliase und die Pfade der neu angelegten Nodes geschrieben. Daraus entstand eine Rewrite-Map für Artikel-URLs aus dem alten System.
Beim Import war aber noch ein weiteres Problem zu lösen: das Markup der Inhalte. In den Artikeln konnten die Redakteure alle Inhaltselemente von TYPO3 nutzen, beschränkten sich in der Praxis aber nahezu vollständig auf Text und Text mit Bild. Dennoch waren recht viele Transformationen notwendig, um diese Inhalte in Neos nutzen zu können. Besonders anspruchsvoll waren dabei die bodytext-Felder und Bilder.
Im bodytext entfernten wir zahlreiche leere Tags. Alle Zeilen wurden in p-Tags eingeschlossen, sodass Neos diese beim Rendern der Seite nicht übernimmt. Zu guter Letzt parsten wir die link-Tags und setzten sie in reguläre HTML-Links um. Eine Wiederverwendung des Parser-Codes aus TYPO3 war leider durch weitreichende Abhängigkeiten nicht möglich, so dass wir einen eigenen Parser implementierten.
Die Migration der Bilder war vor allem eine taktische Aufgabe. Neos unterstützt von sich aus nur einzelne Bilder, die Darstellung mehrerer Bilder in einem Element mit den zahlreichen Möglichkeiten aus CMS ist nicht möglich. Da im neuen Design der Website jedoch nur noch einzelne Bilder oder Carousel-Slideshows vorgesehen waren, konnte eine gute Lösung gefunden werden. Elemente aus mehreren Bildern transformierten wir in ein von uns definiertes Carousel-Element, einzelne Bilder übernahmen wir direkt. „Text mit Bild“-Elemente zerlegte der Importer in ihre Bestandteile, um mit Neos‘ Bordmitteln auszukommen und zugleich an Flexibilität zu gewinnen.
Tooling für die Zukunft
Der Import lief in diesem Projekt mit einem Custom-Tool, und auch in
Zukunft wird dies für die meisten Projekte wohl die beste Wahl sein.
Nodes anzulegen sowie Inhalte aus TYPO3 und anderen Systemen auszulesen und zu transformieren sind dennoch Probleme, die absehbar immer wieder auftreten werden. Für diese Aufgaben sollte eine Sammlung von
Bausteinen entstehen, mit deren Hilfe die Entwicklung von
Import-Projekten vereinfacht werden kann.
Neben der Migration von Inhalten im Zusammenhang mit einem
Relaunch sollten viele dieser Bausteine auch für die Anbindung von
Datenquellen für den laufenden Betrieb nutzbar sein.
Fazit
Neos bietet durch seine Flexibilität gute Möglichkeiten zur Umsetzung des Content-First-Prinzips bei der Projektplanung und -umsetzung. Dennoch ist es nach wie vor schwierig, ein Projekt konsequent auf diese Art und Weise umzusetzen. Bei der Migration von bestehendem Content ist das Problem naturgemäß um einiges größer – wie soll man Content, der in vielen Fällen mit dem Fokus auf Optik statt auf Struktur entstanden ist, nachträglich strukturieren?
Für Centurion Magazine war der bestehende Inhalt bereits strukturiert, da der Artikel als logische Einheit bereits vorhanden war. Sollte das bei der Migration einer Website nicht der Fall sein, kann mit guter Planung dennoch eine Struktur eingeführt werden. So lassen sich beispielsweise die Inhalte bestimmter Website-Bereiche in spezifische Nodes umwandeln, um aus Text mit Bild aussagekräftige Standort-Nodes zu erzeugen oder Bilder in Portfolio-Elemente zu verwandeln.
Den Mehraufwand, der dafür nötig ist, wird der Kunde nicht immer gern akzeptieren. Hier liegt es dann am Entwickler, den Kunden von den Vorteilen einer solchen Lösung zu überzeugen: gezieltes Templating, einfacheres Handling für die Redakteure und eine Struktur, die zukünftig eine umfangreiche Nutzung der Daten zulässt.
Die Überschrift des Artikels passt irgendwie nicht so ganz zum Inhalt, denn unter „Umzug leicht gemacht“ stelle ich mir irgendwie etwas anderes vor ;)
Ich bin auch davon ausgegangen, dass man in dieser Artikelreihe so gut wie alles für einen möglichen Umzug von TYPO3 CMS zu TYPO3 NEOS erfährt. Ein paar Codebeispiele von einer Agentur sind da leider zu wenig und fördern dies nicht.
Die Überschrift zu diesen Artikel sollte angepasst werden. Es ist total irreführend! Beim nächsten Mal sollte das besser gehen!!!!!