Per Ajax erzeugte Teaser-Box

Per Ajax erzeugte Teaser-Box
mit aktuellen Listings aus
einer Datenbank-Anwendung
(Forum, Produkt-Datenbank)

 

 
Hintergrund und Einsatzbeispiel: Ein typisches Portal-Dokument besteht in der Regel aus einer Kombination von länger gültigen, quasi statischen und Request-spezifischen, also dynamischen Seitenanteilen. Typische Beispiele für dynamische Anteile sind das Login-Formular oder die Anzeige aktueller Forenbeiträge. Für das Caching eignen sich lediglich die statischen Seitenanteile, zumal die dynamischen Fragmente für sich genommen in der Regel weniger performance-intensiv sind als die komplette Assemblierung einer Seite.
Seit ZMS 2.8 ist die DTML-basierte Konfiguration der Cache-Fragmente obsolet geworden und es wird der Einsatz von AJAX (Asynchrones JavaScript und XML) empfohlen. Erläutert wird das Ajax-Prinzip an einem Beispiel: im Teaser-Bereich des primären Dokumentes ('Homepage') werden kleine Boxen mit aktuellen Datenbank-Abfragen eingeblendet, die von einem anderen Server stammen.

Aufgabe: Konfiguration eines Speziellen Teaser-Objektes, das es erlaubt, diverse Content-Boxen dynamisch in den Teaser-Bereich zu integrieren.

Prinzip: Zunächst werden Methoden benötigt, welche die zu integrierenden Datenströme erzeugen, z.B. durch eine Datenbank-Abfrage oder ein XHTML-Fragment von einem zweiten Server, welches mit der API-Funktion http_import(url) in eine REQUEST-Variable (String-Typ) gewandelt wird.
Bei externen Quellen ist das Zope-seitige Preprocessing erforderlich, da per Ajax ein direktes Abgreifen per Client über einen anderen Domian-Namen als den des Container-Dokuments aus Sicherheitsgründen nicht möglich ist.

Beispielhaft wird eine DTML-Methode gezeigt, die aus Latin1-XHTML von einem externen Server einen lokal integierbaren UTF8-Strom erzeugt. (Stattdessen wäre auch jedes beliebige andere DTML denkbar, das die erforderlichen XHTML-Konstrukte liefert.)

# DTML Methode /ajax/forum/teaser #

<dtml-call "RESPONSE.setHeader('Expires', '-1')">
<dtml-call "RESPONSE.setHeader('Cache-Control', 'no-cache')">
<dtml-call "RESPONSE.setHeader('Pragma', 'no-cache')">
<dtml-call "REQUEST.set('teaserforum', http_import('http://www.test-forum.de/forumraw/id1/aktuell'))">
<dtml-var "_.unicode(teaserforum,'latin-1').encode('utf-8')">

JavaScript-Basiscode: Dann wird für die Darstellung wird ein ganz basaler JavaScript-Schnipsel benötigt, der das mit obiger DTML-Methode erzeugte HTML-Fragment in das Ausgabe-Dokument asynchron 'reinziehen' kann.

# JAVASCRIPT Ajax-Beispielcode #

<script type="text/javascript">
<!--
var http = false;
if(navigator.appName == "Microsoft Internet Explorer") {
  http = new ActiveXObject("Microsoft.XMLHTTP");
} else {
  http = new XMLHttpRequest();
} 
function replace() {
  http.open("GET", "/ajax/forum/teaser", true);
  http.onreadystatechange=function() {
    if(http.readyState == 4) {
      document.getElementById('ajax').innerHTML = http.responseText;
    }
  }
  http.send(null);
}
replace();
-->
</script>

<div id="ajax"></div>

Der JavaScript-Code erzeugt ein Objekt 'http', das über die open()-Methode bzw. eine lokale URL mit Content befüllt wird. Die Methode replace() ersetzt das leere DIV-Element mit ID="ajax" (das die Rolle eines Platzhalter übernimmt) beim Rendern des Dokuments gegen diesen Datenstrom.

Spezielles Objekt: Damit man mehrere Teaser-Boxen adressieren kann, ist es erforderlich, dass die Platzhalter-Objekte bzw. Funktionen eindeutigen Namen erhalten; dafür eignen sich die ZMS-IDs als spezifischer Namens-Appendix; zudem muss der zuführende Content-Strom individuell adressierbar sein. Daher verfügt das Grundmodell des Ajax-Teaser über ein URL-Element, in welches die Datenquelle eingetragen wird. Entsprechend wird für das Darstellung obiges JavaScript mit einige wenigen DTML-Aufrufen (für id und url) angereichert:

Special-Objekt-Konfiguration für den Ajax-Teaser

Special-Objekt-Konfiguration für den Ajax-Teaser: über das Attribut wird die HTML-Quelle angegeben.

# Darstellungs-Template Ajax-Teaser (bodyContentZMSCustom_ajaxteaser) #

<script type="text/javascript">
<!--
var http_<dtml-var id> = false;
if(navigator.appName == "Microsoft Internet Explorer") {
  http_<dtml-var id> = new ActiveXObject("Microsoft.XMLHTTP");
} else {
  http_<dtml-var id> = new XMLHttpRequest();
} 
function replace_<dtml-var id>() {
  http_<dtml-var id>.open("GET", "<dtml-var absolute_url>/<dtml-var "getObjProperty('url',REQUEST)">", true);
  http_<dtml-var id>.onreadystatechange=function() {
    if(http_<dtml-var id>.readyState == 4) {
      document.getElementById('ajax_<dtml-var id>').innerHTML = http_<dtml-var id>.responseText;
    }
  }
  http_<dtml-var id>.send(null);
}
replace_<dtml-var id>();
-->
</script>

<div id="ajax_<dtml-var id>"></div>
Eingabe-Maske

Eingabe-Maske für das Spezielle Objekt Ajax-Teaser

Erstellt von: Dr. F. Hoffmann , erstellt am:  27.06.2008 , zuletzt geändert: 27.06.2008