??changed:
-
<p>Zopebuch: <a href="ZBInhalt">Inhaltsverzeichnis</a>&nbsp;</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>    &lt;dtml-var standard_html_header&gt;

      &lt;dtml-if zooName&gt;

        &lt;p&gt;&lt;dtml-var zooName&gt;&lt;/p&gt;

      &lt;dtml-else&gt;

        &lt;form action="&lt;dtml-var URL&gt;" method="GET"&gt;
          &lt;input name="zooName"&gt;
          &lt;input type="submit" value="What is zooName?"&gt;
        &lt;/form&gt;

      &lt;/dtml-if&gt;  

    &lt;dtml-var standard_html_footer&gt;</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>      &lt;dtml-var unicorn&gt;</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>      &lt;dtml-var standard_html_header&gt;

        &lt;dtml-with REQUEST only&gt;
          &lt;dtml-if zooName&gt;
            &lt;p&gt;&lt;dtml-var zooName&gt;&lt;/p&gt;
          &lt;dtml-else&gt;
            &lt;form action="&lt;dtml-var URL&gt;" method="GET"&gt;
              &lt;input name="zooName"&gt;
              &lt;input type="submit" value="What is zooName?"&gt;
            &lt;/form&gt;
          &lt;/dtml-if&gt;
        &lt;/dtml-with&gt;

      &lt;dtml-var standard_html_footer&gt;</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...]