Mit dem Apronym AJAX, welches für "Asynchronous JavaScript and XML" steht, bezeichnet man eine Technik, mit der Nutzdaten zwischen einer Webseite und eine Webserver ausgetauscht werden, ohne dass die ganze Webseite an sich neu geladen werden muss. Client-seitig wird dabei massiv von JavaScript Gebrauch gemacht, um den asynchronen Datentransfer zu regeln und Manipulationen am DOM-Baum der Webseite vorzunehmen.
Im CMS Typo3 kann man für eigene Extensions recht leicht AJAX-Support implementieren:
Dazu bedient man sich der eID-Schnittstelle von Typo3. Ich gehe an dieser Stelle davon aus, dass eine Extension, der AJAX Support hinzugefügt werden soll vorhanden ist. Zu Testzwecken lässt sich ein brauchbares Grundgerüst aber auch leicht über die Kickstarter Extension erstellen (dazu muss man lediglich eine neue Extension mit mindestens einem Frontend-Plugin erzeugen).
Die Grundidee des eID-Mechanismus ist ganz einfach: Man registriert unter einem Namen '$bezeichner' einen Hook, auf den alle Aufrufe umgeleitet werden, die in ihrer URL ein entsprechendes eID-Tag haben (z.B. /index.php?eID=bezeichner). Passende Aufrufe werden an das angegebene Skript weitergereicht und der normale Rendering Prozess wird (noch bevor überhaupt eine Ausgabe passiert ist) abgebrochen. Anstatt eine eigene Renderengine anzubinden, kann man ganz hervorragend einen AJAX-Request auswerten und eine passende JSON-Response als Antwort generieren.
Wie geht man konkret vor?
Parallel zu den bestehenden Verzeichnissen im Pluginordner erzeugt man nun ein Verzeichnis für die benötigten AJAX/JSON Skripte.
Nun müssen die notwendigen Skripte anlegt werden:
Als erstes gilt es, eine PHP Klasse mit einer Datenstruktur für die gewünschten JSON-Operationen zu generieren. Der Einfachhalt halber hat has Beispiel nur drei Felder: Ein Flag mit Namen 'isSuccess', das kennzeichnet ob die letzte Aktion (bzw. der AJAX Auruf ansich) erfolgreich war. Ein Feld für Nachrichten( Fehlercodes o.Ä.) und einen generischen Data-Bereich.
messages[] = $message; } } ?> ]]>
Source: 4-json_response.php
Damit man während der AJAX-Requests seine Antworten im gewohnten Typo3-Kontext (leider werden auf diese Weise nicht alle bekannten Typo3 Umgebungsvariablen gesetzt) erzeugen kann, empfiehlt es sich als Basis für eine eigene Klasse tslib_pibase zu wählen:
Während der Abarbeitung des Skriptes wird eine Instanz der Datenklasse erzeugt, gefüllt und nachher als JSON-Antwort zurück gegeben.
request = $this->getRequest(); $this->response = new tx_json_response(); $content = $this->processRequest(); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Last-Modified: ' . gmdate( "D, d M Y H:i:s" ) . 'GMT'); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); $charset = $GLOBALS["cfgApplCharset"].""; header('Content-Type: text/javascript; charset='.$charset.''); header('Content-Disposition: inline; filename=json.js'); header('Content-Length: '.strlen($content)); echo $content; } function getRequest() { $input = fopen("php://input", 'r'); $content = fread($input, $this->MAX_REQUEST_LENGTH); return json_decode($content, true); } function processRequest() { // prepare a demo response $this->response->isSuccess = true; $this->response->addMessage("Request successful"); $this->response->data = Array(); $this->response->data["stringValue"] = "my string value"; $this->response->data["num"] = 42; return $this->response->asString(); } } $output = t3lib_div::makeInstance("json_test"); $output->main($action); ?> ]]>
Source: 4-json_test.txt
Alternativ kann man natürlich auch mit einem sehr abgespeckten Antwort Skript arbeiten - mit dem Nachteil, dass man sich alle benötigten Komponenten von Hand dazu laden muss:
$feUserObj = tslib_eidtools::initFeUser(); // Initialize FE user object tslib_eidtools::connectDB(); //Connect to database
Damit Typo3 zukünftig die Richtige Klasse instantiiert, muss man noch den Notwendigen Hook/Handler fuer die AJAX-Aufrufe registrieren. Dies geschieht durch einen kleinen Eintrag in der ext_localconf.php:
// json handler configuration $TYPO3_CONF_VARS['FE']['eID_include']['bezeichner'] = 'EXT:myExtensionName/json/class.ajaxhandler.php';
Wenn man nun einen entsprechenden Aufruf startet (z.B. /index.php?eID=bezeichner) wird unser Skript gestartet.
Der String 'bezeichner' kann natürlich durch jedes eigene Schlüsselwort ersetzt werden, welches aber in der weiteren Typo3 Installation nicht anderweitig genutzt werden darf (hier biete sich evtl. an, den Extension Key mit einzucodieren).
Client-Seitig kann man JSON-Requests durch passende asynchrone JavaScript-Aufrufe triggern und verarbeiten. Der Einsatz eines JavaScript-Frameworks drängt sich hier natürlich gerade zu auf. Ich empfehle an dieser Stelle natürlich mal wieder JQuery.
Weiteres Vorgehen:
Die meisten Web-Applikationen werden nicht mit einem einzelnen AJAX-Handler auskommen:
Anstatt nun für jede Funktion einen eigenen Handler zu registrieren, könnte man eine zentrale Factory-Klasse schreiben, die abhängig von einem (bisher noch nicht vorhandener) Action-Parameter (z.B. /?eID=json&action=list) eine passende Klasse instantiiert, ausführt und dessen Ergebnis zurück liefert.
Eine kleine Beispiel-Extension habe ich auch noch parat: Download hier: 4-T3X_ajaxdemo.t3x
Kommentare