Dynamische Erstellung eines TYPO3-Seitenbaums aus externen Datenbanken: 10.000 Seiten in 15 Minuten
Oft sind die Daten für eine Website bereits vorhanden, liegen in einer Datenbank vor und müssen für den Einsatz auf der Website lediglich gefiltert und minimal bearbeitet werden. Die Idee liegt also auf der Hand, Teile des Seitenbaums und verschiedene Content-Elemente automatisch zu generieren. Die Extension „ml_dbsync“ kann diese Aufgabe übernehmen und die Selektion und Transformation erledigen. Es gibt drei mögliche Einsatzszenarien für „ml_dbsync“:
- Einmaliger Import: Ist dann interessant, wenn zum Beispiel eine bestehende Website zu TYPO3 migriert und anschließend nur noch in TYPO3 bearbeitet werden soll.
- Manueller Import zu unregelmäßigen Zeitpunkten: Ist sinnvoll, wenn zwar eine externe Datenbank genutzt wird, die Webdaten aber nur zu nicht fest definierten Zeitpunkten aktualisiert werden müssen.
- Regelmäßige Synchronisation: Existiert zum Beispiel eine externe Produktdatenbank, die stets auf dem aktuellen Stand gehalten wird, kann sie durch regelmäßige Synchronisation als Datenquelle für den Produktbereich genutzt werden.
Die Arbeitsweise der Extension „ml_dbsync“ basiert auf den folgenden fünf Grundideen:
- Usability: Dynamisch erstellte Seiten und Content-Elemente müssen vom Benutzer schnell und einfach als solche erkannt werden.
- Sicherheit: Die Daten der externen Datenbank müssen in eine eigene Tabelle in TYPO3 kopiert werden. Dadurch ist für die externe Tabelle nur ein Lese-Zugriff notwendig und sensible Daten müssen nicht auf dem Webserver gespeichert werden.
- Flexibilität: Ein Benutzer muss in der Lage sein, dynamisch erzeugte Seiten und Content-Elemente zu bearbeiten oder zu löschen. Dies ist insbesondere dann wichtig, wenn die Inhalte als Einmal-Import verwendet werden.
- Integrität: Um die Datenintegrität zu gewährleisten, müssen die Daten der externen Datenbank stets Priorität haben. Das heißt, wenn ein Benutzer ein dynamisch erstelltes Content-Element ändert, muss es bei der nächsten Synchronisation trotzdem mit den Daten von der externen Datenbank überschrieben werden.
- Konsistenz: Die erstellten Seiten und Content-Elemente müssen auch nach wiederholter Synchronisation immer die gleiche ID erhalten. Das ist notwendig, damit zum Beispiel Links auf dynamisch erstellte Seiten weiterhin und nach jeder späteren Synchronisation funktionieren.
Die Funktionsweise von „ml_dbsync“ im Beispiel
Zur Veranschaulichung der Funktionsweise dient hier die Website der fiktiven Werkzeugfirma „Binford“. Die Website besteht aus den zwei Bereichen „The Company“ und „The Tools“. Aber nur der Bereich „The Tools“ soll dynamisch erzeugt werden. Dort werden die Seiten mit den Kategorien erzeugt und darunter die jeweiligen Werkzeugseiten mit allen Inhalten.
Die Daten der Seiten werden in einer externen Datenbank mit zwei Tabellen gespeichert. Die Tabelle „main_categories“ enthält die Kategorien und die Tabelle „tools“ beinhaltet alle Daten der Werkzeuge.
Die XML-Konfigurationsdatei
Bevor die eigentliche Arbeit beginnen kann, muss „ml_dbsync“ über den Extension-Manager installiert werden. Dabei können die Standardeinstellungen übernommen werden. Anschließend muss eine XML-Konfigurationsdatei für den Synchronisationsprozess erstellt werden. „ml_dbsync“ ermöglicht die Synchronisation mit beliebig vielen externen Datenbanken. Die importierten Daten können an jeder gewünschten Stelle im Seitenbaum eingefügt werden.
Wenn unterhalb einer Seite dynamische Inhalte eingefügt werden sollen, muss dafür eine eigene XML-Konfigurationsdatei erstellt werden. Im Internet ist eine komplette XML-Beispieldatei zu finden, die die Konfiguration dokumentiert [1]. Im Folgenden sind die wichtigsten Bereiche einer solchen Datei erklärt.
Zuerst werden innerhalb eines „database“-Blocks die Verbindungsparameter zur externen Datenbank festgelegt.
<database type=”array”> <host>localhost</host> <username>root</username> <password></password> <database>t3_db_sync_data</database> </database>
Listing 1
Ein optionaler „libraries“-Block erlaubt die Einbindung von PHP-Klassen, die spezielle Funktionen während des Synchronisationsprozesses zur Verfügung stellen können.
<libraries type=”array”> <numIndex index=”0” type=”array”> <includeFile>fileadmin/data/php_libraries.inc</includeFile> <class>ux_importFunctions</class> </numIndex> </libraries>
Listing 2
Der „pages“-Block ist der Hauptbestandteil der Datei und definiert, welche Felder der externen Datenbank welchen Feldern in der TYPO3-Datenbank zugeordnet werden sollen. Das erste Beispiel (Listing 3) erzeugt neue Seiten aus den Daten der externen Datenbanktabelle „main_categories“. Nur die Daten aus den Feldern „uid“ und „name“ werden benötigt und den Feldern „id“ und „title“ der TYPO3-Datenbank zugeordnet. Das geschieht über eine einfache, aber flexible SQL-Technik (Felder mit dem Schlüsselwort "AS" umbenennen). Das <doktype>-Tag gibt schließlich an, welchen Seitentyp die neu erstellten Seiten haben sollen.
<pages type=”array”> <numIndex index=”1” type=”array”> <sql type=”array”> <select>uid AS id, name AS title</select> <from>main_categories</from> <groupby></groupby> <orderby>name</orderby> </sql> <doktype>1</doktype>
Listing 3
Die zweite Ebene wird auf die gleiche Art und Weise generiert (Listing 4). Der einzige Unterschied besteht darin, dass nun nicht alle Einträge der ausgewählten Tabelle verwendet werden sollen, sondern nur die, die zur übergeordneten Seite gehören. Diese Zuordnung geschieht über den Platzhalter „##pages[1][id]##“, der die ID des übergeordneten Datensatzes enthält.
<pages type=”array”> <numIndex index=”1” type=”array”> <sql type=”array”> <select>uid AS id, name AS title</select> <from>tools</from> <where>category_id=’##pages[1][id]##’</where> <groupby></groupby> <orderby>uid</orderby> </sql> <doktype>1</doktype>
Listing 4
Im obigen Beispiel werden nur Werkzeuge aus der Tabelle „tools“
ausgewählt, deren Wert im Feld „category_id“ mit der „id“ der
übergeordneten Seite (aus „main_categories“ erstellt) übereinstimmt.
Zusätzlich sollen auf den Seiten der zweiten Ebene einige Content-Elemente erzeugt werden. Das geschieht mit einem „contents“-Block (Listing 5). Dieser ist ähnlich wie der „pages“-Block aufgebaut. Der wichtigste Unterschied besteht im <Ctype>- Tag, das angibt, welche Art Content-Element erstellt werden soll. In diesem Beispiel werden Content-Elemente vom Typ „text“ erstellt. Es lassen sich auch Content-Elemente anderer Typen wie Bilder oder Tabellen anlegen.
<contents type=”array”> <numIndex index=”1” type=”array”> <sql type=”array”> <select>’T’ AS id, text AS bodytext</select> <from>tools</from> <where>uid=’##pages[1][1][id]##’</where> </sql> <CType>text</CType>
Listing 5
Da in den Quelldaten der externen Datenbank spezielle Steuerzeichen enthalten sind (z. B. zur Formatierung in Fettschrift), ist es notwendig, sie durch die entsprechenden HTML-Pendants (bei Fettschrift <strong>-Tags) zu ersetzen. Das geschieht durch die Funktion „parseText()“, die in der anfangs inkludierten Klassenbibliothek definiert wurde. Die Funktion wird über einen „parseFunc“-Block dem Content-Element zugeordnet (Listing 6).
<parseFunc type=”array”> <numIndex index=”1” type=”array”> <function>ux_importFunctions->parseText</function> <field>bodytext</field> </numIndex> </parseFunc> </numIndex>
Listing 6
Mit Hilfe von „parseFunc“-Blöcken können beliebige Operationen auf den importierten Daten ausgeführt werden, was eine sehr große Flexibilität beim Import ermöglicht.
Bevor der Synchronisationsprozess gestartet werden kann, muss die XML-Konfigurationsdatei noch mit einer Seite im Seitenbaum verknüpft werden. Sie dient als Startpunkt für die dynamisch erstellten Seiten. Nachdem die XML-Datei und der Startpunkt im DB-Sync-Backend-Modul ausgewählt wurden, kann die Synchronisierung mit dem "Import/Update"-Button gestartet werden. Nach der erfolgten Synchronisierung zeigt „ml_dbsync“ einen Ergebnisbericht, in dem etwaige Fehler, die Zahl der erstellten und aktualisierten Seiten und Content-Elemente aufgelistet werden. Im Seitenbaum sind die dynamisch erzeugten Seiten dann durch das alternative Seitensymbol von den normalen Seiten zu unterscheiden.
Soll eine Synchronisation mit der externen Datenbank nicht nur manuell
angestoßen werden, sondern in regelmäßigen Abständen erfolgen, kann
„ml_dbsync“ zusammen mit der Extension „gabriel“ eingesetzt werden und
so zum Beispiel alle 24 Stunden Daten abrufen.
Produktiveinsatz
In diesem Artikel wurde der Einsatz von „ml_dbsync“ nur anhand der Website einer fiktiven Firma gezeigt. Die Extension wird aber seit über einem Jahr produktiv für den realen Betrieb eingesetzt. Auf der Website www.muepro.com wird der gesamte Produktbereich in zehn Sprachen über die „ml_dbsync“ erzeugt und gepflegt. Die folgende Liste gibt einen kleinen Überblick über Features, die über die Extension realisiert werden können:
- Übersichtsseiten mit Produktbildern werden automatisch generiert.
- HTML-Tabellen werden aus verschiedenen Datenquellen zusammengesetzt.
- Querverlinkungen zwischen Produkten werden berechnet und erstellt.
- Formatierungsanweisungen werden in HMTL konvertiert.
- JavaScript-mouseover-Effekte werden in speziellen Bereichen eingesetzt.
- Bilder werden, falls nötig, automatisch optimiert und in der Größe angepasst.
Der komplette Synchronisationsprozess für circa 10.000 Seiten dauert etwa 15 Minuten.
Die Zukunft
Die aktuelle Version von „ml_dbsync“ läuft stabil mit der TYPO3-Version 3.8.x. Eine Weiterentwicklung für TYPO3-4.x mit Unterstützung für Versionierung, Workspaces und TemplaVoilà erscheint als logischer nächster Schritt. Diese Weiterentwicklungen sind bereits geplant, die Finanzierung jedoch noch offen.
Mit Erscheinen dieser Ausgabe des T3N Magazins sollte die Extension bereits im TYPO3-Extension-Repository (TER) und bei TYPO3xdev zur Verfügung stehen.