Preview eigener Inhaltselemente – tt_content_drawItem-Hook

Wer aufmerksam die Neuerungen der TYPO3-Versionen verfolgt, weiß, dass es seit Version 4.3 einen Hook gibt, über den die Darstellung von Inhaltselementen im Backend-Modul „Page“ beeinflusst werden kann. Interessant wird das vor allem bei eigenen Extensions, die ansonsten als Preview nur ihren Extensionnamen und ein einsames „CODE:“ ausgeben.

Was ist zu tun, um den Hook zu nutzen?

Blick in den Core

Um zu verstehen, wie Featuresgenutzt werden können, bietet sich es in der Regel an, zumindest grob zu schauen, wie das Features implementiert ist. Konkret heißt das nun einen Blick in die zuständige Klasse tx_cms_layout einen Blick zu werfen.

Rund um die Zeile 1700 findet sich dann der Hook:

    // Hook: Render an own preview of a record
$drawItemHooks =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem'];

if (is_array($drawItemHooks)) {
	foreach($drawItemHooks as $hookClass)    {
		$hookObject = t3lib_div::getUserObj($hookClass);

		if(!($hookObject instanceof tx_cms_layout_tt_content_drawItemHook)) {
			throw new UnexpectedValueException('$hookObject must implement interface tx_cms_layout_tt_content_drawItemHook', 1218547409);
		}

		$hookObject->preProcess($this, $drawItem, $outHeader, $out, $row);
	}
}

Nun hat man eigentlich alle nötigen Informationen, wie man den Hook nutzen kann:

  1. Den Namen bzw. Registrierungsstelle: $GLOBALS[‚TYPO3_CONF_VARS‘][‚SC_OPTIONS‘][‚cms/layout/class.tx_cms_layout.php‘][‚tt_content_drawItem‘]
  2. Man sieht bereits, dass das Interface tx_cms_layout_tt_content_drawItemHook implementiert werden muss.
  3. Bei der Verarbeitung stehen die Variablen $this, $drawItem, $outHeader, $out und $row zur Verfügung.
  4. Aus dem Context bzw. einem Blick ins Interface erschließt sich, welche Variablen für die Ausgabe im BE befüllt werden müssen.

Hook-Klasse

Zunächst erstellt man seine Hook-Klasse, die das Interface tx_cms_layout_tt_content_drawItemHook implementiert, wie wir bereits im Code oben als Voraussetzung gesehen haben. Somit muss die Methode preProcess() auch vorhanden sein, die letztlich für die Manipulation/Änderung der Vorschau zuständig ist. In ihr wird auf bestimmte Parameter (in der Regel wohl den CType der eigenen Extension) geprüft und die die Werte für $headerContent und $itemContent nach Belieben geändert. In $row steht uns hierbei der Datenbankeintrag aus tt_content zur Verfügung.
Über ein $drawItem=FALSE wird erzwungen, dass die neu gesetzten Inhalte genutztw erden (ansonsten fällt TYPO3 in den nicht-gewollten Default-Fall zurück).
Nicht zu Vergessen ist noch, dass das verwendete Interface inkludiert wird.

Die Klasse könnte dann etwa wie folgt aussehen:

require_once(PATH_typo3 . 'sysext/cms/layout/interfaces/interface.tx_cms_layout_tt_content_drawitemhook.php');

/**
 * Class which hooks into tx_cms_layout and do additional tt_content_drawItem processing.
 *
 * @package TYPO3
 * @subpackage example
 */
class tx_example_tt_content_drawItem implements tx_cms_layout_tt_content_drawItemHook {
	/**
	 * Preprocesses the preview rendering of a content element.
	 *
	 * @param	tx_cms_layout	$parentObject:  Calling parent object
	 * @param	boolean         $drawItem:      Whether to draw the item using the default functionalities
	 * @param	string	        $headerContent: Header content
	 * @param	string	        $itemContent:   Item content
	 * @param	array		$row:           Record row of tt_content
	 * @return	void
	 */
	public function preProcess(tx_cms_layout &$parentObject, &$drawItem, &$headerContent, &$itemContent, array &$row) {
		switch($row['CType']) {
			case 'tx_example_pi1':
				$drawItem = FALSE;
				$headerContent = '[EXAMPLE]' . $headerContent;
				$itemContent = $this->getPi1Preview($row);
			break;
		}
	}

	/**
	 * Preview of a content element *_pi1.
	 *
	 * @todo Implement some useful preview rendering ;-)
	 * @param	 array        $row:           Record row of tt_content
	 * @return	 string
	 */
	private function getPi1Preview($row) {
		return 'EXAMPLE';
	}
}

Registrieren des Hooks

Jetzt muss die Klasse nur noch eingebunden und der Hook registriert werden. Dies geschieht in der ext_localconf.php der Extension:

require_once(t3lib_extMgm::extPath($_EXTKEY).'hooks/class.tx_example_tt_content_drawItem.php');
    // Call hook for manipulation of frontend user object
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem'][$_EXTKEY] = t3lib_extMgm::extPath($_EXTKEY).'hooks/class.tx_example_tt_content_drawItem.php:tx_example_tt_content_drawItem';

Links:

Das könnte dich auch interessieren …

5 Antworten

  1. Julian sagt:

    Freut mich, dass es Dir geholfen hat. Bin durch ein Usergruppen-Treffen der WUeTUG drauf gestoßen und hatte es dann irgendwann auch geschafft, etwas aufbereitet online zustellen.

    Was Dein problem noch angeht: Flexforms werden eben „nur“ als XML-String in der Datenbank gespeichert. Daher bekommst Du an dieser Stelle erste inmal nur diesen String. Du kannst aber mit PHP das XML selbst parsen und die passenden teile für Deien Vorschau rausziehen. Oder versteh ich das Problem falsch?
    Abschauen könntest Du Dir evtl. dafür auch etwas in der Extension „news“. Ich meine, Georg hat hier auch die Vorschau etwas aufgebohrt, um die Plugin-Einstellungen sichtbar zu machen (d.h. Flexforminhalte)

  2. Markus Meier sagt:

    Oh mann …. du bist meine Rettung.
    Ich suche nun seit Tagen nach einer Lösung um den Pageview zu manipulieren.

    Thnx a lot.

    PS: Ein Problem habe ich noch … das FlexForm Feld wird als einziger String ausgegeben …. XML ist raus.
    So ist bissel schwierig, die Felder zu parsen 🙂

  3. roman sagt:

    Beim Einsatz von TemplaVoila funktioniert die Technik nicht, das TemplaVoila ein vollstaendig eigenes Page-Modul mit sich bringt.
    Alternativen sind evtl. (aber funktional nicht gleichwertig) die Hooks von TemplaVoila, Stichwort: renderElementClass

  4. Björn Breder sagt:

    switch($row[‚CType‘]) sollte besser switch($row[‚list_type‘]) heissen 😉

    • Julian sagt:

      Prinzipiell ja, da hast Du Recht. Es kommt aber auf die Extension an. Bei uns gibt es einige Installationen/Extensions, wo wirklich neue CTypes eingeführt werden und folglich der switch richtig ist.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert