COA_INT in Extensions

In Typo3 spielt der Cache eine grosse Rolle. Die Performance von gecachten Seiten ist eine viel höhere als ohne Cache, da Typo3 die Inhalte nicht neu rendern muss.

Oft benötigt man aber Abschnitte in der Seite, die jedesmal neu gerendert werden müssen.

Als einfaches Beispiel nehmen wir die Uhrzeit - diese soll aktuell den Zeitpunkt des Seitenaufrufes anzeigen. Kommt dieses Objekt aber aus dem Cache, so sehen wird die Uhrzeit zum Zeitpunkt des Erstaufrufes der Seite.

Im Typoscript gibt es für Objekte, die nicht gecachet werden einen speziellen Typ: COA_INT

Möchten wir also immer die aktuelle Uhrzeit auf der Seite haben, so definieren wir ein Objekt als COA_INT mit der Uhrzeit, und dieses Objekt wird jedesmal neu gerendert. Nachfolgend habe ich ein Beispiel mit der Uhrzeit aus Typoscript, einmal als gecachtes COA - und einmal als ungecachtes COA_INT - Objekt. Da diese Seite gecachet ist, wird es deutlich, wenn man die Seite mit F5 aktualisiert.

TypoScript
#Uhrzeit als COA - wird gecachet
lib.uhrzeit = COA
lib.uhrzeit {
    10 = TEXT
    10.data = date:U
    10.strftime = %D - %H:%M:%S
}
#Uhrzeit als COA_INT - wird nicht gecachet
lib.uhrzeit_int = COA_INT
lib.uhrzeit_int {
    10 = TEXT
    10.data = date:U
    10.strftime = %D - %H:%M:%S
}
Uhrzeit als COA

05/26/16 - 00:34:31

Uhrzeit als COA_INT

05/26/16 - 00:34:31

OK, wir sehen, wie wunderbar dieses Prinzip funktioniert.

Doch wie sieht das in Extensions aus ? Diese Technik können wir auch in Extensions wunderbar gebrauchen. Oftmals beobachten wir, das Autoren die gesamte Extension ohne cache ausgeben, um neu gerenderte Inhalte zu erzwingen. Das hat aber den Nachteil, das diese Inhalte nicht mehr durchsuchbar sind und natürlich auch die Seite an Performance einbüsst. Dabei benötigt es doch nur einen kleinen Abschnitt in der Extension, der nicht gecachet werden soll.

An dieser Stelle möchte ich mich bei Jo Hasenau bedanken, der dieses aufgegriffen hat und den folgenden Beispielcode zur Verfügung gestellt hat.

Um ein Typoscript-Objekt in einer Extension zu rendern, gibt es ein Funktion:
$this->cObj->cObjGetSingle

Wir benötigen also nur den entsprechenden Typoscript und können ihn in der Extension einbinden. Als Beispiel soll die Extension cachetest dienen, deren TS-Code und PHP-Code nachfolgend zu sehen ist:

TypoScript
plugin.tx_cachetest_pi1 = COA
plugin.tx_cachetest_pi1 {
    10 = TEXT
    10.data = date:U
    10.strftime = %D - %H:%M:%S
    10.wrap = First Called:&nbsp;|<br /><br />
    20 = USER
    20 {
        userFunc = tx_cachetest_pi1->main
        userFunc {
            basket = COA_INT
            basket {
                wrap = <hr />|
                10 = TEXT
                10.value = Basket (COA_INT):
                20 = USER
                20.userFunc = tx_cachetest_pi1->callTimeBasket
            }
            singleView = COA
            singleView {
                wrap = <hr />|
                10 = TEXT
                10.value = Single View (COA):
                20 = USER
                20.userFunc = tx_cachetest_pi1->callTimeSingle
            }
            combinedView = COA
            combinedView {
                wrap = <hr />|
                10 = COA
                10 {
                    wrap = |<br />
                    10 = TEXT
                    10.value = CombinedView (COA) Part1 (COA):
                    20 = USER
                    20.userFunc = tx_cachetest_pi1->callTimeCombined1
                }
                20 = COA_INT
                20 {
                    wrap = |<br />
                    10 = TEXT
                    10.value = CombinedView (COA) Part2 (COA_INT):
                    20 = USER
                    20.userFunc = tx_cachetest_pi1->callTimeCombined2
                }
            }
        }
    }
}
PHP
<?php
 
require_once(PATH_tslib.'class.tslib_pibase.php');
 
class tx_cachetest_pi1 extends tslib_pibase {
	var $prefixId = 'tx_cachetest_pi1';  // Same as class name
	var $scriptRelPath = 'pi1/class.tx_cachetest_pi1.php'; // Path to this script relative to the extension dir.
	var $extKey = 'cachetest'; // The extension key.
	var $pi_checkCHash = TRUE;
 
	/*
	* The main method of the PlugIn
	*
	* @param string  $content: The PlugIn content
	* @param array  $conf: The PlugIn configuration
	* @return The content that is displayed on the website
	*/
	
	function main($content,$conf) {
		$this->conf=$conf;
		$this->pi_setPiVarDefaults();
		$this->pi_loadLL();
		foreach ($conf['userFunc.'] as $part => $setup) {
			if(!strpos($part,'.')) {
				$content .= $this->cObj->cObjGetSingle($setup,$conf['userFunc.'][$part.'.']);
			}
		}
		return $this->pi_wrapInBaseClass($content);
	}
 
	function callTimeBasket() {
		return strftime('%D - %H:%M:%S',time());
	}
 
	function callTimeSingle() {
		return strftime('%D - %H:%M:%S',time());
	}
 
	function callTimeCombined1() {
		return strftime('%D - %H:%M:%S',time());
	}
 
	function callTimeCombined2() {
		return strftime('%D - %H:%M:%S',time());
	}
}
 
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cachetest/pi1/class.tx_cachetest_pi1.php']) {
	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/cachetest/pi1/class.tx_cachetest_pi1.php']);
}
 
?>

etwas tricky ist nun der Versuch auf ein extra Typoscript-Schnipsel zu verzichten.

Hierzu nehme ich ein Typoscript-Objekt und baue es in PHP nach.

Folgendes Objekt in Typoscript:

TypoScript
object = COA_INT
object {
   10 = USER
   10.userFunc = tx_cachetest_pi1->callTimeSingle
}

kann man auch in ein PHP-Array packen und anschliessend über cObjGetSingle einbinden, sozusagen Typoscript on-the-fly:

PHP
function COA_INTonthefly() {
	$TS['conf']='COA_INT';
	$TS['conf.']['10']='USER';
	$TS['conf.']['10.']['userFunc']='tx_cachetest_pi1->callTimeSingle';
	return $this->cObj->cObjGetSingle($TS['conf'],$TS['conf.']);
}

nachfolgend wollen wir uns noch die Ausgabe dieser Extension anschauen:

First Called: 05/26/16 - 00:34:31


Basket (COA_INT):05/26/16 - 00:34:32
Single View (COA):05/26/16 - 00:34:32
CombinedView (COA) Part1 (COA):05/26/16 - 00:34:32
CombinedView (COA) Part2 (COA_INT):05/26/16 - 00:34:32
Object COA_INT generated on-the-fly
05/26/16 - 00:34:32
1 Kommentar
#1 Thomas Rinklin schrieb am 29.08.2007 16:40

Vielen dank für diese Erklärung. Ich war überrascht, dass diese frisch gerenderten _INT-Objekte so einfach in die gecachete seite eingefügt werden.

 

nun zu meiner ergänzung/frage. diese userFunc-Function bekommt ja auch ein $content und ein $conf parameter übergeben. nur ist das $conf nur mit dem namen der userFunc gefüllt. alle anderen werte aus den templates sind nicht enthalten. wie kommt man nun an diese werte?

ich habe dazu mit der zeile

$TS['conf.'] = $this->conf;

diese werte in mein in php erzeugtes USER_INT Objekt.

 

da ich noch nicht wirklich viel mit typo3 gemacht habe und sie sich offensichtlich schon mit diese cache-thematik auseinandergesetzt haben, wollte ich sie fragen, was sie diesem vorgehen halten.

einen Kommentar schreiben
Typo3