Inhalt von anderer Seite mit TYPO3 und TemplaVoila

Wenn man TemplaVoila intensiv verwendet kommt es vor, dass man Inhalt von einer anderen Seite einbinden möchte. Ein Beispiel wäre dafür der Inhalt eines globalen Footers. Man erstellt eine Seite in der der Inhalt des Footers definiert wird und fügt diesen Inhalt im Haupttemplate in einen definierten Marker ein. Problematisch wird das ganze wenn man ein Flexibles Inhaltselement (FCE, Flexible Content Elements) verwendet, welches selber wieder ein Feld für Inhaltelemente hat. Das Ergebnis ist, das alle Inhalte doppelt angezeigt werden, da die Inhaltselemente vom FCE ebenfalls die Seiten-UID der Hauptseite besitzen.

Üblicherweise verwendet man zum einfügen von Inhalten einer anderen Seite foldendes Typoscript:

lib.field_footer = CONTENT
lib.field_footer {
  table = tt_content
  select {
    pidInList = 26
  }
}

Hier habe ich ein FCE erstellt welches mir eine Spaltenweise Ansicht ermöglicht.

Doppelte Inhaltselemente

Inhaltselemente im FCE werden doppelt dargestellt.

Wie man sieht erscheinen alle Inhaltselemente innerhalb der Spalten doppelt.

Um dieses Problem zu beheben muss man die Datenstruktur von TemplaVoila aufbröseln und die einzelenen UIDs der Inhaltelemente herausfiltern. Das habe ich mit einer extra Klasse ermöglicht, die ich in Typoscript via „userFunc“ abrufe.

Ich habe hier einmal zwei Versionen für TYPO3 < 6.0 und >= 6.0. Der Unterschied ist nicht groß, allerdings ist t3lib_div ab TYPO3 6.0 als veraltet markiert.

Quellcode für TYPO3 < 6.0

<?php
class user_content_from_pages {

	/**
	 * @var tslib_cObj
	 */
	public $cObj;

	/**
	 * Get content from other pages with TemplaVoila (TYPO3 < 6.0 version)
	 *
	 * @param string $content
	 * @param array $conf
	 * @return string
	 */
	public function displayTemplaVoilaContent($content, $conf) {
		//Enable stdWrap for userFunc params
		$page_id = $this->cObj->stdWrap($conf['page_id'], $conf['page_id.']);
		$field_name = $this->cObj->stdWrap($conf['field_name'], $conf['field_name.']);

		$row = NULL;
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'deleted=0 AND hidden=0 AND uid=' . intval($page_id), '', '', 1);
		$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);

		$row_overlay = NULL;
		if($GLOBALS['TSFE']->sys_language_content) {
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages_language_overlay', 'deleted=0 AND hidden=0 AND pid=' . intval($page_id) . ' AND sys_language_uid=' . $GLOBALS['TSFE']->sys_language_content, '', '', 1);
			$row_overlay = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
			$row = array_merge($row, $row_overlay);
		}

		//Convert TemplaVoilas XML to array
		$tv_flex_config = t3lib_div::xml2array($row['tx_templavoila_flex']);
		//Get the contents
		$content_uids = array();
		if(isset($tv_flex_config['data']) && isset($tv_flex_config['data']['sDEF']) && count($tv_flex_config['data']['sDEF']['lDEF']) > 0) {
			foreach($tv_flex_config['data']['sDEF']['lDEF'] as $key => $fields) {
				if($key == $field_name) {
					$content_uids = array_merge($content_uids, t3lib_div::trimExplode(',', $fields['vDEF']));
				}
			}
		}

		//Check if a different content renderer has been set
		//"register : uid" contains the current content uid that will be rendered
		if(isset($conf['contentRenderer'])) {
			$content_renderer = array(
				'contentRenderer' => $conf['contentRenderer'],
				'contentRenderer.' => $conf['contentRenderer.'],
			);
		}
		else {
			//Default content renderer
			$content_renderer = array(
				'contentRenderer' => 'RECORDS',
				'contentRenderer.' => array(
					'tables' => 'tt_content',
					'source.' => array(
						'data' => 'register:uid',
					),
					'dontCheckPid' => '1',
				)
			);
		}

		//Get the content and return it
		$content = "";
		foreach($content_uids as $content_uid) {
			$GLOBALS['TSFE']->register['uid'] = $content_uid;
			$content .= $this->cObj->cObjGetSingle($content_renderer['contentRenderer'], $content_renderer['contentRenderer.']);
		}

		return $content;
	}
}

?>

Quellcode für TYPO3 >= 6.0

<?php

class user_content_from_pages {

	/**
	 * @var tslib_cObj
	 */
	public $cObj;

	/**
	 * Get content from other pages with TemplaVoila (TYPO3 > 6.0 version)
	 *
	 * @param string $content
	 * @param array $conf
	 * @return string
	 */
	public function displayTemplaVoilaContent($content, $conf) {
		//Enable stdWrap for userFunc params
		$page_id = $this->cObj->stdWrap($conf['page_id'], $conf['page_id.']);
		$field_name = $this->cObj->stdWrap($conf['field_name'], $conf['field_name.']);

		$row = NULL;
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'deleted=0 AND hidden=0 AND uid=' . intval($page_id), '', '', 1);
		$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);

		$row_overlay = NULL;
		if($GLOBALS['TSFE']->sys_language_content) {
			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages_language_overlay', 'deleted=0 AND hidden=0 AND pid=' . intval($page_id) . ' AND sys_language_uid=' . $GLOBALS['TSFE']->sys_language_content, '', '', 1);
			$row_overlay = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
			$row = array_merge($row, $row_overlay);
		}

		//Convert TemplaVoilas XML to array
		$tv_flex_config = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($row['tx_templavoila_flex']);

		//Get the contents
		$content_uids = array();
		if(isset($tv_flex_config['data']) && isset($tv_flex_config['data']['sDEF']) && count($tv_flex_config['data']['sDEF']['lDEF']) > 0) {
			foreach($tv_flex_config['data']['sDEF']['lDEF'] as $key => $fields) {
				if($key == $field_name) {
					$content_uids = array_merge($content_uids, \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $fields['vDEF']));
				}
			}
		}

		//Check if a different content renderer has been set
		//"register : uid" contains the current content uid that will be rendered
		if(isset($conf['contentRenderer'])) {
			$content_renderer = array(
				'contentRenderer' => $conf['contentRenderer'],
				'contentRenderer.' => $conf['contentRenderer.'],
			);
		}
		else {
			//Default content renderer
			$content_renderer = array(
				'contentRenderer' => 'RECORDS',
				'contentRenderer.' => array(
					'tables' => 'tt_content',
					'source.' => array(
						'data' => 'register:uid',
					),
					'dontCheckPid' => '1',
				)
			);
		}

		//Get the content and return it
		$content = "";
		foreach($content_uids as $content_uid) {
			$GLOBALS['TSFE']->register['uid'] = $content_uid;
			$content .= $this->cObj->cObjGetSingle($content_renderer['contentRenderer'], $content_renderer['contentRenderer.']);
		}

		return $content;
	}

}

?>

Den Quellcode einfach in einer Datei im Fileadmin ablegen z.B. „fileadmin/scripts/content_from_pages.php“. Nun kann man die Klasse im Typoscript hinzufügen und werwenden

page.includeLibs.content_from_pages = fileadmin/scripts/content_from_pages.php
lib.field_footer = USER
lib.field_footer {
  userFunc = user_content_from_pages->displayTemplaVoilaContent
  # Seiten ID der fernen Seite
  page_id = 16
  # TemplaVoila-Feldname der fernen Seite wo der Inhalt liegt
  field_name = field_content
}

Das Ergebnis kann sich sehen lassen.

Korrekte FCE anzeige

Die Inhalte werden nun korrekt angezeigt.

Update
Danke an Freddy für die Frage und die Lösung des Problems bei mehreren Sprachen (http://lists.typo3.org/pipermail/typo3-project-templavoila/2013-April/005683.html). Ich habe den Beitrag dahingehend geändert.

6 Comments

  1. Super Sache, aber wie soll das auf einer mehrsprachigen Website funktionieren?
    Es gibt keine Feld tx_templavoila_flex in der Tabelle pages_language_overlay.

  2. Michael Oehlhof sagt:

    Bin auch begeistert von dem Script, genau das was ich in einem Projekt gerade brauchte.
    Allerdings habe ich ein Problem mit der Mehrsprachigkeit.
    Auf einer Seite wird statt englisch die deutsche Version angezeigt, auf einer anderen bleibt die englische Seite leer.

  3. Aggy sagt:

    Klasse Sache! Danke dafür

  4. Tobi sagt:

    Sehr hilfreicher Artikel – danke!!

    Ein Hinweis:
    ich habe in Zeile 29 (Quellcode für TYPO3 < 6.0) folgendes ergänzt:

    if(!empty($row_overlay))$row = array_merge($row, $row_overlay);

    Sonst kommt eine Exception beim Sprachwechsel, wenn die Zielseite nicht übersetzt ist.

    Grüße

  5. Steffen sagt:

    Hallo zusammen!
    Für alle, die es – wie ich – nicht raffen: Der „field_name“ (= field_content), der per TypoScript übergeben wird, muss dem Feldnamen des gewünschten Inhalts aus seiner Datenstruktur von TemplaVoila entsprechen. In meinem Fall musste es daher
    „field_name = field_maincontent“
    heißen. Dann klappt es auch 😉
    Grüße
    Steffen

  6. Sebastian sagt:

    Hallo,
    super Script! Funktioniert auch wunderbar. Ich stehe nur vor dem Problem, statt dem Content der page_id = 16 den Content des Firstchild dieser Seite ausgeben lassen zu wollen. Gibts dazu eine Idee?
    Grüße

Schreibe einen Kommentar

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

question razz sad evil exclaim smile redface biggrin surprised eek confused cool lol mad twisted rolleyes wink idea arrow neutral cry mrgreen

*

Sicherheitsfrage * Time limit is exhausted. Please reload the CAPTCHA.