Typoscript in Plugins richtig eingesetzt
Mit Typoscript stellt TYPO3 ein mächtiges Werkzeug bereit, daß leider in vielen Extensions nur sehr kümmerlich genutzt wird. Die Ursache dafür liegt vermutlich darin, daß TYPO3 die Entwickler bei der Einbindung von Typoscript größtenteils im Regen stehen läuft. Dieser Artikel soll hier Abhilfe schaffen.
Wenn man in TYPO3 ein Plugin schreibt, dann werden der Pluginklasse in der main-Methode zwei Parameter von TYPO3 übergeben: $content und $conf. Die Variable $conf enthält dabei ein Array mit den per Typoscript angegebenen Konfigurationen. Es ist nun recht einfach diese Daten statisch auszulesen.
Schwieriger wird es aber, wenn man das übergebene Typoscript dynamisch auswerten will.
Stellen wir uns folgende Datenbank-Tabelle vor:
CREATE TABLE tx_testext_demo { uid int(11) NOT NULL auto_increment, pid int(11) DEFAULT '0' NOT NULL, title tinytext NOT NULL, content mediumtext NOT NULL, date int(11) unsigned DEFAULT '0' NOT NULL, image text NOT NULL, }
Die Tabelle ist natürlich verkürzt und enthält nur die wichtigsten Felder, die uns interessieren. Wir haben ein normales Text-Feld (title). Die Spalte content enthält eine ausführliche Beschreibung und soll in der TCA als RTE-Feld konfiguriert werden. Das Feld date enthält ein Datum und image offensichtlich ein Bild.
Unser Ziel wird es sein, alle Felder per Typoscript zu formatieren und dafür passende Marker bereitzustellen.
In unserer Testextension würden wir zunächst die passende Typoscript-Konfiguration festlegen. Das erfolgt üblicherweise in einer Datei mit dem Namen setup.txt, die sich im Verzeichnis static befindet. Für das Plugin legen wir die folgende Konfiguration fest:
plugin.tx_testext_pi1 { # Der Ordnung halber zuerst ein Rooteintrag für die Tabelle. Der Name ist hier frei wählbar demotable { # Jetzt für jede Spalte ein paar Konfigurationen. Hier benennen wir die Konfiguration genauso wie die Spalten in der DB # Es geht einfach los mit dem Titel, der als Überschrift 2 gezeigt werden soll. # Die eckigen Klammer müssen durch Spitze ersetzt werden. title.wrap = [h2]|[/h2] # Beim Content benötigen wir vollen RTE-Support content.parseFunc =< lib.parseFunc_RTE # Das Datum soll nur gezeigt werden, wenn ein Wert eingegeben wurde. Ansonsten wir ein - gezeigt date = CASE date { default = TEXT default.field = date default.strftime = %d. %B %Y 2 = TEXT 2.value = - key { field = date ifEmpty = 2 } } # Und abschließend noch das Bild konfigurieren image < tt_content.image.20 image { imgList.field = image imgPath = uploads/tx_testext/ maxH = 50 maxW = 70 } }
Wie man sieht, haben wir alle wichtigen Angaben im Typoscript-Setup untergebracht. Bei Bedarf kann das problemlos von einem TYPO3-Admin angepaßt werden. Nun müssen wir diese ganzen Angaben nur noch richtig in das Plugin einbinden. Die Auswertung von Typoscript übernimmt in TYPO3 die Klasse tslib_cObj. Jedes TYPO3-Plugin bekommt vor dem Start automatisch ein Instanz dieser Klasse in der Variablen $this->cObj untergeschoben. Das cObj selbst hat eine sehr wichtige Instanz-Variable mit dem Namen $data. In allen Typoscript-Operationen haben wir Zugriff auf dieses Datenarray. Bei der Formatierung des image haben wir oben folgende Zeile angegeben:
image.imgList.field = image
Wenn das cObj diese Zeile auswertet, dann sucht es im $data-Array nach dem Wert von "image". Damit das klappt, müssen wir unserem cObj vor der Auswertung also die Daten, des aktuellen Records mitteilen. Danach unterscheiden wir für den Aufruf zwei Fälle:
- Für den Wert im Record wurde ein Datentyp wie TEXT, CASE, IMAGE usw. definiert
- Der Wert enthält nur einen normalen Wrap
Den zweiten Fall haben wir in unserem Beispiel bei den Feldern title und content. Die Spalte date ist dagegen ein CASE und image ist ein IMGTEXT. Bei image wird diese Angabe aus tt_content.image.20 herauskopiert.
Für den zweiten Fall rufen wir in unserem cObject einfach die Methode stdWrap() auf. Bei Fall 1 wird es etwas komplizierter, weil wir hier die Methode cObjGetSingle() verwenden müssen. Der folgende Codeauszug soll das nun alles demonstrieren:
function main($content, $conf) { // $conf muss unbedingt das definierte Typoscript enthalten // Mit einer Debug-Ausgabe kann man das leicht überprüfen // t3lib_div::debug($conf, 'demoplugin'); // Wir holen zuerst die Daten für die Records der Tabelle tx_testext_demo $recConf = $conf['demotable.']; // Wir merken uns die Ursprungsdaten des cObj $pluginData = $this->cObj->data; // Jetzt die Datenabfrage $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*','tx_testext_demo', $where); while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { // Wir setzen wir den Record als Datenarray in unser cObj $this->cObj->data = $row; // Ein Array mit den Markern vorbereiten // Jetzt iterieren wir über alle Felder des Records und starten die Formatierung // Nun je nach Konfiguration den Typoscript-Aufruf einbinden if($recConf[$colname]) { // Hier behandeln wir den ersten Fall. Wir verwenden cObjGetSingle. // Vorher muss der aktuelle Wert dem cObj mitgeteilt werden $this->cObj->setCurrentVal($value); $value = $this->cObj->cObjGetSingle($recConf[$colname],$recConf[$colname.'.']); // Den Wert setzen wir nach der Abfrage zurück $this->cObj->setCurrentVal(false); } else { // Fall 2 ist ein einfacher stdWrap $value = $this->cObj->stdWrap($value, $recConf[$colname.'.']); } // Die Marker erstellen wir generisch aus den Feldnamen } // $markerArray enthält nun alle formatierten Daten des Records und kann in das HTML-Template integriert werden // Das ist hier aber nicht mehr relevant ... } // Abschließend das cObject wieder zurücksetzen $this->cObj->data = $pluginData; }
Wie man sieht, ist das nach Abzug der Kommentare nur recht wenig Code. Man kann nun aber die volle Power von Typoscript in seinem Plugin einsetzen. Das Bild wird einfach gerendert, das Datum und das RTE-Feld werden richtig formatiert, ohne daß man selbst umständlich die entsprechenden Methoden in cObj aufrufen muss. Mit Typoscript geht das viel eleganter! :)