??changed: - <p>Zopebuch: <a href="ZBInhalt">Inhaltsverzeichnis</a> </p> <p><em>Dieses Dokument ist momentan leider noch nicht vollst�ndig �bersetzt.</em></p> <h1>Kapitel 8: Variablen und DTML f�r Fortgeschrittene</h1> <p>DTML ist eine Sprache, die in der Regel "tut, was man meint". Das ist vor allem dann gut, wenn alles so l�uft, wie man es sich vorstellt. Ist das aber nicht der Fall, so ist dies eher eine schlechte Eigenschaft. Dieses Kapitel soll Ihnen zeigen, wie Sie DTML dazu bringen, das zu tun, was Sie <em>wirklich</em> meinen. DTML hat einen gewissen Ruf, sehr komplex zu sein, und zu einem Teil stimmt dies auch. DTML ist sehr einfach, wenn es um einfache Layout-Aufgaben geht, die wir bisher kennen gelernt haben. Will man allerdings DTML f�r komplexere Aufgaben benutzen, so m�ssen wir ein gutes Verst�ndnis der Herkunft von Variablen und deren Inhalten haben.</p> <p>Nun folgt ein wirklich schwieriges Beispiel, �ber das fast alle "Neulinge" einmal stolpern. Stellen wir uns vor, wir haben ein DTML-Dokument namens <em>zooName</em>. Der Inhalt sieht aus wie folgt: <pre> <dtml-var standard_html_header> <dtml-if zooName> <p><dtml-var zooName></p> <dtml-else> <form action="<dtml-var URL>" method="GET"> <input name="zooName"> <input type="submit" value="What is zooName?"> </form> </dtml-if> <dtml-var standard_html_footer></pre> <p></p> <p>Sieht einfach aus, nicht? Diese DTML-Seite ruft sich selber auf, da die HTML-Aktion auf die <em>URL</em> Variable verweist, welches nat�rlich die URL des DTML Documentes ist.</p> <p>Wenn nun also die <code>zooName</code> Variable existiert, wird unsere Seite diese ausgeben. Existiert die Variable hingegen nicht, so wird ein Formular angezeigt, in dem wir diese Variable eingeben k�nnen. Wenn wir auf "submit" klicken, wird der eingegebene Wert die "if"-Abfrage wahr machen, und der folgende Code sollte den eingegebenen Wert auf der Seite ausgeben.</p> <p>Leider ist dies einer der F�lle, in dem DTML nicht das tut, was man m�chte, weil der Name des Dokuments ebenfalls <em>zooName</em> ist, und so wird nicht die Variable aus dem Request-Objekt benutzt, sondern das Dokument selbst, welches sich wiederum selber aufruft und so weiter, bis Zope mit einem "exessive Recursion" Fehler den L�ffel abgibt. In den folgenden Abschnitten soll gezeigt werden, wie sich dieser Fehler beseitigen l�sst und wie man DTML dazu bringt, das zu tun, was wir meinen. </p> <h2>Wie Variablen nachgesehen werden</h2> <p>Genau genommen gibt es zwei Wege, den Fehler im <em>zooName</em> Dokument zu beheben. Der erste besteht darin, das Dokument in<em>zopeNameFormOrReply</em> umzubenennen, sich f�r den Rest seiner Tage an diesen Sachverhalt zu erinnern und diesen Fehler niemals wieder zu machen, ohne zu wissen, was genu eigentlich der Fehler ist. Der zweite Weg besteht darin, sich dar�ber klar zu werden, wie Variablen und deren Werte in Zope gesucht und gefunden werden. Dann k�nnen wir Zope genau sagen, <em>wo</em> im Namensraum ("Namespace") wir den Namen der Variablen aufgel�st haben m�chten.</p> <p>Der DTML-Namensraum gleicht einer Ansammlung von Objekten auf einem Stapel ("<em>Stack</em>"). Ein Stapel ist eine Liste von Objekten, die durch "Drauflegen" ("push") und "Herunternehmen" ("pop") von neuen oder vorhandenen Objekten ver�ndert werden kann. Zope erzeugt immer dann einen DTML-Namensraum, wenn DTML Dokumente oder -Methoden ausgef�hrt werden. Dieser Namensraum dient dann dazu, DTML-Variablennamen aufzul�sen. <p> Es ist sehr wichtig, die inneren Abl�ufe im Namensraum zu verstehen, damit sich akkurat voraussagen l�sst, auf welche Weise Zope unsere Variablen findet. Einige der schwierigsten DTML-Probleme lassen sich durch genaues Verst�ndnis des DTML-Namensraum l�sen.</p> <p>Wenn Zope Variablennamen im DTML-Namensraum stack sucht, so schaut es zuerst auf das Objekt, welches "oben" auf dem Stapel liegt. Kann der Name dort nicht gefunden werden, so ist das n�chst tiefere Objekt auf dem Stack an der Reihe und so weiter. Auf diese Weise arbeitet sich Zope bis auf den "Boden" des Stapels vor und versucht, den Variablennamen aufzul�sen. Bleibt diese Suche erfolglos, so wird ein Fehler generiert und angezeigt.</p> <p> Suchen wir nach einem nicht-existenten Namen, z. B. <em>unicorn</em>:</p> <pre> <dtml-var unicorn></pre> <p></p> <p> Gibt es keine Variable dieses Namens (<em>unicorn</em>), so erhalten wir bei Ansehen dieses Dokumentes den in <a href="#7-1">Abbildung 7-1</a> gezeigten Fehler..</p> <p><a name="7-1"></a> <img src="Figures/7-1.png" alt="DTML Fehler �ber eine nicht gefundene Variable."> </p><p><b>Abbildung 7-1</b> DTML Fehlermeldung �ber eine unbekannte Variable.</p> <p></p> <p>Der Namestack ist allerdings anf�nglich nicht einfach leer, sondern er enth�lt bereits vor der Ausf�hrung von DTML einige Objekte. </p> <h2>DTML-Namensr�ume</h2> <p>DTML-Namensr�ume werden dynamisch f�r jede Anforderung ("Request") erzeugt. Wird zum Beispiel eine DTML-Methode oder ein Dokument durch einen Web-Browser angefordert, enth�lt der DTML-Namensraum zwei Objekte: Das client- und das Request-Objekt, wie in <a href="#7-2">Abbildung 7-2</a></p> <p><a name="7-2"></a><img src="Figures/7-2.png" alt="Initialer DTML-Namensraum-Stack."> gezeigt. </p><p><b>Abbildung 7-2</b> Initialer DTML-Namensraum-Stack.</p> <p></p> <p>Das client-Object liegt oben auf dem Namensraum-Stack. Um welches Objekt es sich handelt, h�ngt davon ab, ob wir ein DTML-Dokument oder eine -Methode betrachten. In unserem obigen Beispiel heisst das client-Objekt <em>zooName</em>. Dies ist auch der Grund f�r den Fehler. Die Formular-Variable kommt eigentlich aus dem Request-Objekt, aber das Client-Objekt wird zuerst gefunden, weil es oben auf dem Stack liegt./p> <p>Der Namensraum des request-Objektes kommt immer an letzter Stelle im DTML-Namensraum, daher wird dieses Objekt auch als letztes nach Variablennamen durchsucht. Dies bedeutet, dass wir genau spezifieren m�ssen, welchen Namensraum wir verwenden m�chten. Dies geschieht mit Hilfe des DTML-Tags <code>with</code></p> <pre> <dtml-var standard_html_header> <dtml-with REQUEST only> <dtml-if zooName> <p><dtml-var zooName></p> <dtml-else> <form action="<dtml-var URL>" method="GET"> <input name="zooName"> <input type="submit" value="What is zooName?"> </form> </dtml-if> </dtml-with> <dtml-var standard_html_footer></pre> <p></p><p>In diesem Fall gibt der "with" tag an, dass im <code>REQUEST</code>-Namensraum und <em>nur</em> im <code>REQUEST</code>-Namensraum, nach "zooName" gesucht werden soll.</p> <h3>Das DTML-Client-Objekt</h3> <p>Das Client-Objekt h�ngt ebenfalls davon ab, ob wir eine Methode oder ein Dokument ausf�hren. Handelt es sich um ein Dokument, so ist das Client-Objekt immer das Dokument selbst; in anderen Worten, das Client-Objekt eines DTML-Dokumentes ist immer das Dokument selbst. <p> <p>Eine DTML-Methode dagegen kann verschiedene Client-Objekte haben, je nachdem, auf welche Weise die Methode aufgerufen wird. Nehmen wir z. B. eine Methode, welche den Inhalt eines Ordners ("Folder") anzeigt; in diesem Fall ist das Client-Objekt der Ordner, dessen Inhalt [1191 more lines...]