Heute ist Samstag, der 16. Dezember 2017

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:

  1. CREATE TABLE tx_testext_demo {
  2. uid int(11) NOT NULL auto_increment,
  3. pid int(11) DEFAULT '0' NOT NULL,
  4. title tinytext NOT NULL,
  5. content mediumtext NOT NULL,
  6. date int(11) unsigned DEFAULT '0' NOT NULL,
  7. image text NOT NULL,
  8. }

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:

  1. plugin.tx_testext_pi1 {
  2. # Der Ordnung halber zuerst ein Rooteintrag für die Tabelle. Der Name ist hier frei wählbar
  3. demotable {
  4. # Jetzt für jede Spalte ein paar Konfigurationen. Hier benennen wir die Konfiguration genauso wie die Spalten in der DB
  5. # Es geht einfach los mit dem Titel, der als Überschrift 2 gezeigt werden soll.
  6. # Die eckigen Klammer müssen durch Spitze ersetzt werden.
  7. title.wrap = [h2]|[/h2]
  8. # Beim Content benötigen wir vollen RTE-Support
  9. content.parseFunc =< lib.parseFunc_RTE
  10. # Das Datum soll nur gezeigt werden, wenn ein Wert eingegeben wurde. Ansonsten wir ein - gezeigt
  11. date = CASE
  12. date {
  13. default = TEXT
  14. default.field = date
  15. default.strftime = %d. %B %Y
  16. 2 = TEXT
  17. 2.value = -
  18. key {
  19. field = date
  20. ifEmpty = 2
  21. }
  22. }
  23. # Und abschließend noch das Bild konfigurieren
  24. image < tt_content.image.20
  25. image {
  26. imgList.field = image
  27. imgPath = uploads/tx_testext/
  28. maxH = 50
  29. maxW = 70
  30. }
  31. }

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:

  1. 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:

  1. Für den Wert im Record wurde ein Datentyp wie TEXT, CASE, IMAGE usw. definiert
  2. 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:

  1. function main($content, $conf) {
  2. // $conf muss unbedingt das definierte Typoscript enthalten
  3. // Mit einer Debug-Ausgabe kann man das leicht überprüfen
  4. // t3lib_div::debug($conf, 'demoplugin');
  5. // Wir holen zuerst die Daten für die Records der Tabelle tx_testext_demo
  6. $recConf = $conf['demotable.'];
  7. // Wir merken uns die Ursprungsdaten des cObj
  8. $pluginData = $this->cObj->data;
  9. // Jetzt die Datenabfrage
  10. $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*','tx_testext_demo', $where);
  11. while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
  12. // Wir setzen wir den Record als Datenarray in unser cObj
  13. $this->cObj->data = $row;
  14. // Ein Array mit den Markern vorbereiten
  15. $markerArray = array();
  16. // Jetzt iterieren wir über alle Felder des Records und starten die Formatierung
  17. while(list($colname,$value)=each($row)){
  18. // Nun je nach Konfiguration den Typoscript-Aufruf einbinden
  19. if($recConf[$colname]) {
  20. // Hier behandeln wir den ersten Fall. Wir verwenden cObjGetSingle.
  21. // Vorher muss der aktuelle Wert dem cObj mitgeteilt werden
  22. $this->cObj->setCurrentVal($value);
  23. $value = $this->cObj->cObjGetSingle($recConf[$colname],$recConf[$colname.'.']);
  24. // Den Wert setzen wir nach der Abfrage zurück
  25. $this->cObj->setCurrentVal(false);
  26. }
  27. else {
  28. // Fall 2 ist ein einfacher stdWrap
  29. $value = $this->cObj->stdWrap($value, $recConf[$colname.'.']);
  30. }
  31. // Die Marker erstellen wir generisch aus den Feldnamen
  32. $markerArray['###DEMO_'.strtoupper($colname).'###'] = $value;
  33. }
  34. // $markerArray enthält nun alle formatierten Daten des Records und kann in das HTML-Template integriert werden
  35. // Das ist hier aber nicht mehr relevant
  36. ...
  37. }
  38. // Abschließend das cObject wieder zurücksetzen
  39. $this->cObj->data = $pluginData;
  40. }

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! :)

Kommentare

Armin, 05-08-09 11:18:
Sehr nützliche Anleitung - vielen Dank!
Add comment
*









*

*

* - required field