Deutsche Zope User Group
Gast 2 Benutzer online

Dieses Verfahren ist insbesondere dann n�tzlich, wenn Sie Seitenbereiche ausf�llen m�chten, die mit dynamischem Inhalt gef�llt werden sollen. So hat zum Beispiel eine Tabelle, die normalerweise zehn Zeilen enth�lt, in der Seitenvorlage nur eine Zeile. F�gt man nun aber 9 Blindzeilen ein, so hat das Layout der Vorlage weit gr��ere �hnlichkeit mit dem Endergebnis.

Nicht immer m�ssen Sie auf tal:replace="nothing" zur�ckgreifen, um Blindinhalt in Ihre Seitenvorlagen einzuf�gen. So haben Sie zum Beispiel bereits gesehen, dass alles innerhalb der Elemente tal:content und tal:replace normalerweise entfernt wird, wenn die Seitenvorlage umgesetzt wird. Bei diesen Elementen sind also keine zus�tzlichen Verfahren n�tig, um den Blindinhalt zu entfernen.

Standardinhalt

Sie k�nnen den Inhalt eines Elements bestehen lassen, indem Sie den Ausdruck default zusammen mit tal:content oder tal:replace verwenden. Hierzu ein Beispiel:

          

Spam

Dieser Code wird folgenderma�en umgesetzt:

          

Spam

Meist m�chte man Standardinhalt nicht generell einf�gen, sondern nur, wenn bestimmte Bedingungen erf�llt sind. Ein Beispiel:

          

Dosenfleisch

Hinweis: Python-Ausdr�cke werden weiter unten in diesem Kapitel erkl�rt. Falls die Methode holeEssen einen wahren Wert zur�ckgibt, wird ihr Ergebnis in den Absatz eingef�gt; ansonsten ist das Ergebnis Dosenfleisch zum Abendessen.

Wiederholung

Die meisten Dinge, die Sie mit der Anweisung tal:repeat machen k�nnen, haben Sie bereits in Kapitel 5, "Zope-Seitenvorlagen verwenden", kennen gelernt. Dieser Abschnitt behandelt einige weiterf�hrende Funktionen der Anweisung tal:repeat.

Wiederholungsvariablen

Die Wiederholungsvariablen geh�ren zu denjenigen Themen, die eventuell einer ausf�hrlicheren Erl�uterung bed�rfen. Sie stellen Informationen �ber die aktuelle Wiederholung bereit. F�r repeat-Variablen stehen die folgenden Attribute zur Verf�gung:

Auf den Inhalt einer Wiederholungsvariablen k�nnen Sie mit Pfadausdr�cken oder Python-Ausdr�cken zugreifen. Ein Pfadausdruck ist die dreiteilige Angabe eines Pfades: Name der Variablen repeat, Name der Anweisungsvariablen, Name der gew�nschten Information; also zum Beispiel repeat/item/start. In Python-Ausdr�cken rufen Sie zuerst mit Hilfe der normalen W�rterbuchnotation die Wiederholungsvariable ab, und dann �ber den Attributzugriff die gew�nschte Information. Zum Beispiel: 'python:repeat['item'].start'.

Tipps f�r die Wiederholung

Der folgende Abschnitt erl�utert einige n�tzliche Tipps. Manchmal m�chte man ein Tag wiederholen, allerdings ohne umschlie�endes Tag. Nehmen wir zum Beispiel an, Sie m�chten eine Reihe von Absatz-Tags wiederholen, ohne sie in ein anderes Tag einzuschlie�en. Daf�r verwenden Sie die Anweisung tal:omit-tag: pre>

Zitat

Die Anweisung tal:omit-tag wird weiter unten in diesem Kapitel erkl�rt.

Der folgende Tipp wurde bereits einmal erw�hnt: tal:repeat-Anweisungen d�rfen geschachtelt werden. Dabei muss jedes tal:repeat einen eindeutigen Wiederholungs-Variablennamen haben. Das folgende Beispiel zeigt eine Multiplikationstabelle:

          
DZUG-News

Zopebuch: Inhaltsverzeichnis 

Kapitel 9: Zope-Seitenvorlagen f�r Fortgeschrittene

In Kapitel 5, "Zope-Seitenvorlagen verwenden", haben Sie die grundlegenden Merkmale von Seitenvorlagen kennen gelernt. Dieses Kapitel behandelt komplexere Verfahren, darunter auch neue Arten von Ausdr�cken und Makros.

TAL f�r Fortgeschrittene

Sie haben bereits einiges �ber TAL-Anweisungen (Template Attribute Language: Auszeichnungssprache f�r Seitenvorlagen) erfahren. In diesem Abschnitt gehen wir nun detailliert auf alle TAL-Anweisungen und ihre Optionen ein. Eine Zusammenstellung dieses Materials finden Sie in Anhang C, "Zope-Page-Templates-Referenz".

Inhaltseingabe

Nachdem Sie in Kapitel 5, "Zope-Seitenvorlagen verwenden", bereits gesehen haben, wie tal:content und tal:replace funktionieren, werden Sie in diesem Abschnitt einige darauf aufbauende Tricks zum Einf�gen von Inhalt kennen lernen.

Strukturen einbetten

Normalerweise setzen die Anweisungen tal:replace und tal:content HTML-Tags und -Entit�ten im einzuf�genden Text au�er Kraft, d. h. sie konvertieren HTML-Auszeichnungen in Text. So wandeln sie zum Beispiel < in < um. M�chten Sie diese Umwandlung vermeiden, den Text also als Teil der HTML-Struktur eingeben, so stellen Sie dem Ausdruck das Schl�sselwort structure voran. Beispiel:

    

die Geschichte

Diese Funktion ist n�tzlich, wenn Sie ein HTML- oder XML-Fragment einf�gen, das in einer Eigenschaft gespeichert ist oder von einem anderen Zope-Objekt erzeugt wurde. Nehmen wir zum Beispiel an, Sie haben Nachrichtenmeldungen, die einfache HTML-Auszeichnungen, z. B. f�r Fett- und Kursivschrift, enthalten, und diese Auszeichnungen m�chten Sie auch beibehalten, wenn Sie die Meldungen in eine "Top-News"-Seite einf�gen. Daf�r schreiben Sie:

    

Eine Meldung mit HTML-Auszeichnungen.

Dieser Code f�gt die HTML-Auszeichnungen der Nachrichtenmeldungen in eine Reihe von Abs�tzen ein.

Blindelemente

Seitenelemente, die zwar in der Vorlage, nicht aber im erzeugten Text sichtbar sind, f�gen Sie mit der integrierten Variable nothing ein. Hierzu ein Beispiel:

    
10213 Beispielelement $15.34
X x Y = Z

Dieses Beispiel verwendet Python-Ausdr�cke sowie die Anweisung tal:omit-tag. Beide werden weiter unten in diesem Kapitel n�her erkl�rt.

Falls Sie bereits mit der DTML-Wiederholungsanweisung dtml-in gearbeitet haben, ist Ihnen der Begriff "Stapelung" (Batching) sicher schon untergekommen. Als Stapelung wird die Aufteilung einer gro�en Liste in mehrere kleinere Listen bezeichnet. In der Regel verwendet man dieses Verfahren, um auf einer Web-Seite nur einen Teil der Elemente einer umfangreichen Liste anzuzeigen. Ein anschauliches Beispiel sind Suchmaschinen, die die gro�e Menge der Suchergebnisse in kleinere Gruppen zerlegen. Die Anweisung tal:repeat unterst�tzt die Stapelung zwar nicht, doch Zope enth�lt ein Stapelprogramm. Weitere Informationen dazu finden Sie im Abschnitt "Stapelung" weiter unten in diesem Kapitel.

Eine weitere n�tzliche Funktion, die von tal:repeat nicht bereitgestellt wird, ist das Sortieren. M�chten Sie eine Liste sortieren, so k�nnen Sie entweder ein eigenes Sortierskript schreiben (in Python ist das ganz einfach) oder die Funktion sequence.sort verwenden. Das folgende Beispiel zeigt, wie man eine Liste von Objekten auf dem Titel und dem �nderungsdatum sortiert.

          
Titel �nderungsdatum

Dieses Beispiel ist sehr �bersichtlich, da es die Argumente f�r die Sortierung au�erhalb der Funktion sort definiert. Die Funktion sequence.sort nimmt eine Folge sowie eine Beschreibung, wie diese Folge sortiert werden soll, entgegen. In diesem Beispiel ist die Beschreibung des Sortiervorgangs in der Variablen sort_on definiert. Weitere Informationen zu der leistungsstarken Funktion sequence.sort finden sie im Anhang B, "API-Referenz".

Attributsteuerung

Die Anweisung tal:attributes kennen Sie bereits. Mit Hilfe dieser Anweisung k�nnen Sie Tag-Attribute wie z. B. das Attribut href eines Elementes a dynamisch ersetzen. Auch das Ersetzen mehrerer Attribute eines Tags ist m�glich. Dabei werden die Attribute durch Semikola voneinander getrennt:

        Link

Auch mit XML-Namensr�umen k�nnen Sie Attribute definieren:

        
          Beschreibung

Um Attribute mit XML-Namensr�umen zu erstellen, setzen Sie einfach das XML-Namensraumpr�fix vor den Attributnamen.

Variablen definieren

Mit dem Attribut tal:define k�nnen Sie eigene Variablen definieren. Dies kann aus mehreren Gr�nden w�nschenswert sein, zum Beispiel wenn ein langer Ausdruck innerhalb einer Vorlage immer wieder vorkommt oder eine aufw�ndige Methode h�ufig aufgerufen wird. Eine Variable wird nur einmal definiert, und kann dann in einer Vorlage beliebig oft verwendet werden. Die folgende Liste definiert eine Variable , pr�ft sie und wiederholt auf ihr:

        

Die Anweisung tal:define erstellt die Variable items, die an beliebiger Stelle im Tag ul verwendet werden kann. Achten Sie in diesem Beispiel auch darauf, dass zwei TAL-Anweisungen innerhalb desselben ul-Tags eingesetzt werden. Im Abschnitt "Interaktionen zwischen TAL-Anweisungen" weiter unten in diesem Kapitel finden Sie weitere Informationen zur Verwendung mehrerer Anweisungen innerhalb eines Tags. In diesem Fall weist die erste Anweisung die Variable items zu, w�hrend die zweite Anweisung in einer Bedingung pr�ft, ob items wahr oder falsch (eine leere Folge) ist. Ist die Variable items falsch, so wird das Tag ul nicht angezeigt.

Gehen wir nun davon aus, dass Sie die Liste, falls sie keine Elemente enth�lt, nicht einfach entfernen, sondern stattdessen eine Meldung ausgeben m�chten. Hierf�r f�gen Sie vor der Liste den folgenden Code ein:

        

Keine Elemente vorhanden

Der Ausdruck not:container/objectIds ist dann wahr, wenn container/objectIds falsch ist, und umgekehrt. Weitere Informationen dazu finden Sie im Abschnitt "not-Ausdr�cke" weiter unten in diesem Kapitel.

Hier k�nnen Sie die Variable items nicht verwenden, da sie an dieser Stelle noch nicht definiert ist. Verschieben Sie die Definition von items jedoch in das Tag h4, so k�nnen Sie sie im Tag ul nicht mehr verwenden, da sie in diesem Fall eine lokale Variable von h4 ist. Sie k�nnten die Definition zwar in ein Tag einf�gen, das sowohl h4 als auch ul einschlie�t, doch es gibt auch eine einfachere M�glichkeit. Stellen Sie dem Variablennamen das Schl�sselwort global voran, so ist die Definition vom Tag h4 bis zum Ende der Vorlage g�ltig:

        

Keine Elemente vorhanden

Mit tal:define k�nnen Sie auch mehrere Variablen gleichzeitig definieren, indem Sie diese durch Semikola voneinander trennen:

        

Auf diese Art k�nnen Sie beliebig viele Variablen definieren. Jede dieser Variablen kann einen eigenen globalen oder lokalen G�ltigkeitsbereich haben. Au�erdem k�nnen Sie in einer Definition auf zuvor bereits definierte Variablen verweisen:

        

Wie Sie sehen, kann der gezielte Einsatz von tal:define die Effizienz und Lesbarkeit einer Vorlage wesentlich verbessern.

Tags entfernen

Mit der Anweisung tal:omit-tag k�nnen Sie Tags entfernen. Diese TAL-Anweisung kommt nur selten zum Einsatz, kann gelegentlich aber durchaus n�tzlich sein. Das Attribut omit-tag entfernt ein Tag, hat aber keinerlei Auswirkungen auf den Inhalt dieses Tags. Hierzu ein Beispiel:

        this bleibt

Dieser Code wird umgesetzt als:

        dies bleibt

Wird tal:omit-tagauf diese Art eingesetzt, so funktioniert es fast wie tal:replace="default". Allerdings ist tal:omit-tag n�tzlicher, wenn es zusammen mit anderen TAL-Anweisungen wie z. B. tal:repeat verwendet wird. Das folgende Beispiel zeigt eine M�glichkeit, mit tal:repeat zehn Absatz-Tags zu erstellen:

        
          

1

Dieser Code erstellt zehn Absatz-Tags, wobei das Tag span nicht mit ausgegeben wird.

Das Attribut tal:omit-tag nimmt einen Ausdruck entgegen, wobei in der Regel allerdings ein leerer Ausdruck verwendet wird. Ist der Ausdruck wahr oder gibt es keinen Ausdruck, so wird das Ausdrucks-Tag entfernt. Ist der Ausdruck falsch, so wird das Tag nicht entfernt. Dieses Attribut gibt Ihnen also die M�glichkeit, Tags nur unter bestimmten Umst�nden zu entfernen.

Fehlerbehandlung

Falls in Ihrer Seitenvorlage ein Fehler auftrifft, k�nnen Sie diesen abfangen und eine sinnvolle Fehlermeldung ausgeben. Nehmen wir zum Beispiel an, dass die Vorlage anhand von Formulardaten eine Variable definiert:

        ...
        
        ...

St��t Zope auf ein Problem, kann es zum Beispiel die Variable prefs in den Formulardaten nicht finden, so wird der gesamte Seitenaufbau abgebrochen und stattdessen eine Fehlerseite ausgegeben. Zum Gl�ck l�sst sich dies durch eine eingeschr�nkte Fehlerbehandlung mit der Anweisung tal:on-error vermeiden:

        ...
        
        ...

Tritt w�hrend der Umsetzung einer Vorlage ein Fehler auf, so sucht Zope nach einer tal:on-error-Anweisung, um den Fehler zu behandeln. Zuerst sucht es im aktuellen Tag, dann im umschlie�enden Tag und so weiter, bis es schlie�lich die oberste Ebene erreicht. Findet Zope einen Fehlerbehandler, so ersetzt es den Inhalt des betroffenen Tags durch diesen Ausdruck f�r die Fehlerbehandlung. In diesem Fall enth�lt das Tag span dann eine Fehlermeldung.

Normalerweise wird ein Fehlerbehandler auf einem Tag definiert, das ein logisches Seitenelement umschlie�t, also z. B. auf einer Tabelle. Falls ein Fehler auftritt, w�hrend die Tabelle gezeichnet wird, kann der Fehlerbehandler die Tabelle einfach aus der Seite entfernen oder sie durch eine Fehlermeldung ersetzen.

Eine flexiblere Fehlerbehandlung wird durch den Aufruf eines Skripts erm�glicht:

        
...

Jeder Fehler, der innerhalb von div auftritt, ruft das Skript handleError auf. Beachten Sie, dass es die Option structure dem Skript erm�glicht, zu HTML zur�ckzukehren. Das Skript zur Fehlerbehandlung kann den Fehler untersuchen und je nachdem, um welchen Fehler es sich handelt, unterschiedliche Ma�nahmen ergreifen. Das Skript greift �ber die Variable error im Namensraum auf den Fehler zu. Hierzu ein Beispiel:

        ## Script (Python) "handleError"
        ##binde Namensraum=_
        ##
        error=_['error']
        if error.type==ZeroDivisionError:
            return "

Kann nicht durch null teilen.

" else return """

Ein Fehler ist aufgetreten.

Fehlertyp: %s

Fehlerwert: %s

""" % (error.type, error.value)

Das Skript zur Fehlerbehandlung kann beliebige Aktionen durchf�hren. So kann es zum Beispiel ein Fehlerprotokoll per E-Mail abschicken.

Die Anweisung tal:on-error ist nicht auf eine allgemeine Ausnahmebehandlung angelegt. Zum Beispiel ist sie nicht f�r die Validierung von Formulareingaben geeignet. Diese sollte mit einem Skript durchgef�hrt werden, da Skripte eine leistungsstarke Ausnahmebehandlung erm�glichen. Die Anweisung tal:on-error dient lediglich der Behandlung ungew�hnlicher Probleme, die bei der Umsetzung von Vorlagen auftreten k�nnen.

Interaktionen zwischen TAL-Anweisungen

Gibt es f�r jedes Element nur eine einzige TAL-Anweisung, so folgt deren Ausf�hrung einer einfachen Logik: Zuerst wird die Anweisung des Wurzelelementes ausgef�hrt, dann werden der Reihe nach alle Kindelemente gepr�ft und ihre Anweisungen ausgef�hrt.

Es ist allerdings auch m�glich, dass es auf einem Element mehr als eine TAL-Anweisung gibt. Dabei ist mit Ausnahme der Anweisungen tal:content und tal:replace, die nicht gemeinsam verwendet werden d�rfen, jede Kombination von Anweisungen m�glich.

Verf�gt ein Element �ber mehrere Anweisungen, so werden diese in der folgenden Reihenfolge ausgef�hrt:

  1. define
  2. condition
  3. repeat
  4. content oder replace
  5. attributes
  6. omit-tag

Die Anweisung tal:on-error wird hier nicht genannt, da sie nur aufgerufen wird, wenn ein Fehler auftritt.

Diese Reihenfolge ist nat�rlich nicht willk�rlich festgelegt. H�ufig definiert man Variablen, um sie dann in anderen Anweisungen zu verwenden. Daher steht define an erster Stelle. Anschlie�end muss man entscheiden, ob dieses Element �berhaupt aufgenommen wird, wof�r condition zust�ndig ist. Da die jeweilige Bedingung von gerade definierten Variablen abh�ngen kann, folgt condition direkt hinter define. Es ist n�tzlich, wenn man bestimmte Teile eines Elements bei jeder Iteration von repeat durch andere Werte ersetzen kann. Daher steht repeat vor content, replace und attributes. Da content und replace nicht auf demselben Element ausgef�hrt werden k�nnen, stehen sie nebeneinander. Die Anweisung omit-tag steht an letzter Stelle, da es h�chst unwahrscheinlich ist, dass irgendeine andere Anweisung von ihr abh�ngt, und sie nach repeat aufgef�hrt werden sollte.

Das folgende Beispiel-Tag enth�lt mehrere TAL-Anweisungen:

        

Ex Text

Beachten Sie, dass die Anweisung tal:define zuerst ausgef�hrt wird und die anderen Anweisungen von ihrem Ergebnis abh�ngen.

Wenn Sie TAL-Anweisungen auf Elementen kombinieren, sollten Sie die folgenden drei Einschr�nkungen beachten:

  1. Da HTML die Ausf�hrung mehrerer Attribute mit demselben Namen verbietet, kann auf einem bestimmten Tag nur eine Instanz eines Anweisungstyps ausgef�hrt werden. So ist es zum Beispiel nicht m�glich, zwei Instanzen von tal:define auf demselben Tag auszuf�hren.
  2. Da die Funktionen von tal:content und tal:replace nicht miteinander vereinbar sind, kann auf jedem Tag nur eine dieser beiden Anweisungen ausgef�hrt werden.
  3. Die Reihenfolge, in der TAL-Attribute auf einem Tag notiert werden, hat keinerlei Einfluss auf die Reihenfolge ihrer Ausf�hrung. Unabh�ngig von ihrer Anordnung werden die TAL-Anweisungen auf einem Tag immer in der oben genannten Reihenfolge ausgef�hrt.

M�chten Sie die Reihenfolge von TAL-Anweisungen �berschreiben, so m�ssen Sie das Element in ein anderes Element einschlie�en, z. B. in div oder span, und einige der Anweisungen in dieses neue Element einf�gen. Nehmen wir z. B. an, Sie m�chten eine Folge von Objekten mit einer Schleife durchlaufen, dabei aber einige der Objekte �berspringen. Eine Vorlage, die die Zahlen 0 bis 9 mit einer Schleife durchl�uft und dabei die 3 �berspringt, k�nnte folgenderma�en aussehen:

        
        

Diese Vorlage funktioniert nicht, da die Bedingung vor der Ausf�hrung von repeat gepr�ft wird. Anders ausgedr�ckt: Die Variable n soll zuerst gepr�ft und danach erst definiert werden. Dieses Problem l�sst sich folgenderma�en umgehen:

        

Diese Vorlage l�st das Problem, indem sie die Variable n auf einem umschlie�enden div-Tag definiert. Beachten Sie, dass das Tag div nicht in die Ausgabe �bernommen wird, da es die Anweisung tal:omit-tag enth�lt. Dieser Code sieht zwar nicht sch�n aus, funktioniert aber. M�glicherweise werden zuk�nftige Seitenvorlagen-Versionen eine attraktivere L�sung dieses Problems anbieten.

Formularverarbeitung

In DTML k�nnen Sie Formulare mit einem einfachen Muster verarbeiten, dem so genannten "Formular-/Aktionspaar". Ein Formular-/Aktionspaar besteht aus zwei DTML-Methoden oder Dokumenten: Die bzw. das erste enth�lt ein Formular, das eine Eingabe des Anwenders entgegennimmt, und die bzw. das zweite enth�lt eine Aktion, die auf dieser Eingabe ausgef�hrt wird, und gibt eine Antwort aus. Das Formular ruft die Aktion auf. Weitere Informationen zum Formular-/Aktionsmuster finden Sie in Kapitel 4, "Dynamischer Inhalt mit DTML".

In Zope-Seitenvorlagen l�sst sich das Formular-/Aktionsmuster nicht sonderlich gut einsetzen, da es davon ausgeht, dass die Verarbeitung der Eingabe und die Darstellung der Antwort von demselben Objekt (der Aktion) gehandhabt werden. Anstelle des Formular-/Aktionsmusters empfiehlt sich daher die Verwendung eines Formular-/Aktions-/Antwortmusters. Dabei sollten das Formular und die Antwort Seitenvorlagen sein, die Aktion hingegen ein Skript, das die Eingabe verarbeitet und eine Antwortvorlage zur�ckgibt. Dieses Muster ist flexibler als das Formular-/Aktionsmuster, da das Skript ein beliebiges Objekt aus einer Gruppe von Antwortobjekten zur�ckgeben kann.

Das folgende Beispiel veranschaulicht eine Formularvorlage:

        ...
        
...

F�r die Verarbeitung des Formulars k�nnte ein Skript wie das folgende zust�ndig sein:

        ## Script (Python) "action"
        ##Parameter=name, age
        ##
        container.addPerson(name, age)
        return container.responseTemplate()

Dieses Skript ruft eine Methode f�r die Verarbeitung der Eingabe auf und gibt eine weitere Vorlage zur�ck, die die Antwort enth�lt. Durch den Aufruf dieses Skripts k�nnen Sie eine Seitenvorlage aus Python umsetzen. Die Antwortvorlage enth�lt normalerweise die Best�tigung, dass das Formular richtig verarbeitet wurde.

Das Aktionsskript kann alle m�glichen Aktionen durchf�hren. Es kann eine Eingabe pr�fen, Fehler behandeln, E-Mails verschicken usw. Das folgende Beispiel zeigt, wie eine Eingabe mit einem Skript gepr�ft wird:

        ## Script (Python) "action"
        ##
        if not context.validateData(request):
            # Tritt ein Problem auf, so gib die Formularseitenvorlage
            # zusammen mit einer Fehlermeldung zur�ck
            return context.formTemplate(error_message='Invalid data')

        # Ansonsten gib die Dankesseite zur�ck
        return context.responseTemplate()

Dieses Skript pr�ft die Formulareingabe und gibt die Formularvorlage mit einer Fehlermeldung zur�ck, falls ein Problem aufgetreten ist. An Seitenvorlagen k�nnen Sie Zusatzinformationen mit Schl�sselwortargumenten �bergeben. Die Schl�sselwortargumente stehen der Vorlage �ber die integrierte Variable options zur Verf�gung. Die Formularvorlage kann also einen Abschnitt wie den folgenden enthalten:

        
          Hier folgt die Fehlermeldung.
        

Dieses Beispiel zeigt, wie Sie eine Fehlermeldung ausgeben k�nnen, die �ber Schl�sselwortargumente an die Vorlage �bergeben werden.

Je nach Anwendung k�nnen Sie den Anwender auch an eine Antwortseitenvorlage weiterleiten, statt diese direkt zur�ckzugeben. Obwohl dies die Netzwerkaktivit�t verdoppelt, ist es durchaus sinnvoll, da hierbei im Browser des Anwenders nicht der URL des Aktionsskripts angezeigt wird, sondern der der Seitenvorlage.

Falls Sie keinen Wert auf saubere Formularverarbeitung legen, k�nnen Sie mit Ihren Seitenvorlagen auch eine eingeschr�nkte Version des Formular-/Aktionspaares verwenden. Dies sollten Sie allerdings wirklich nur dann machen, wenn Ihnen an einer Fehlerbehandlung nicht gelegen ist und die Antwort in jedem Fall, unabh�ngig von der jeweiligen Eingabe des Anwenders, dieselbe ist. Da Seitenvorlagen keine Entsprechung zu dtml-call haben, k�nnen Sie einen Trick anwenden, um eine Methode zur Eingabeverarbeitung aufzurufen, ohne deren Ergebnisse einzuf�gen. Hierzu ein Beispiel:

        

Dieses Beispiel ruft die Methode processInputs auf und weist ihr Ergebnis der Variable unused zu.

Ausdr�cke

Seitenvorlagenausdr�cke haben Sie bereits kennen gelernt. Ausdr�cke stellen Werte f�r Vorlagenanweisungen bereit. Ein Beispiel sind Pfadausdr�cke, die Objekte durch einen Pfad wie request/form/age oder user/getUserName beschreiben. Dieser Abschnitt erkl�rt die verschiedenen Arten von Ausdr�cken und Variablen.

Integrierte Variablen

Variablen sind Namen, die in Ausdr�cken verwendet werden k�nnen. Sie haben bereits einige Beispiele f�r integrierte Variablen kennen gelernt, z. B. template, user, repeat und request. Die folgende Liste nennt alle weiteren integrierten Variablen und ihre Verwendungsweise.

nothing
Ein false-Wert, �hnlich einer leeren Zeichenkette, den Sie in tal:replace oder tal:content verwenden k�nnen, um ein Tag oder seinen Inhalt zu l�schen. Es besteht allerdings ein Unterschied zu leeren Zeichenketten: Wenn Sie ein Attribut auf nothing setzen, wird dieses Attribut aus dem Tag gel�scht (oder nicht eingef�gt).
default
Ein besonderer Wert, der nichts �ndert, wenn er in tal:replace, tal:content oder tal:attributes verwendet wird. Er beeinflusst den Vorlagentext nicht.
options
Die an die Vorlage �bergebenen Schl�sselwortargumente, sofern vorhanden. Hinweis: options steht nur zur Verf�gung, wenn eine Vorlage aus Python ausgerufen wird. Wird sie aus dem Internet umgesetzt, so gibt es keine Optionen.
attrs
Ein Attributw�rterbuch des aktuellen Tags in der Vorlage. Als Schl�ssel dienen die Attributnamen und als Werte die urspr�nglichen Werte der Attribute in der Vorlage. Diese Variable kommt selten zum Einsatz.
root
Das Zope-Wurzelobjekt. Damit werden Zope-Objekte von festen Speicherorten geholt, unabh�ngig davon, wo die Vorlage platziert oder aufgerufen wird.
here
Das Objekt, auf dem die Vorlage aufgerufen wird. H�ufig ist es mit dem Beh�lter identisch; falls Sie mit Akquisition arbeiten, kann here allerdings auch ein anderes Objekt bezeichnen. Mit dieser Variable werden Zope-Objekte abgerufen, die sich je nachdem, wie die Vorlage aufgerufen wird, an verschiedenen Stellen befinden k�nnen. here entspricht der Variable context in Python-basierten Skripten.
container
Der Beh�lter (normalerweise ein Ordner), in dem sich die Vorlage befindet. Mit dieser Vorlage werden Zope-Objekte von Speicherorten abgerufen, der relativ zum dauerhaften Speicherort der Vorlage angegeben ist. Die Variablen container und here verweisen auf dasselbe Objekte, falls eine Schablone von ihrem dauerhaften Speicherort aufgerufen wird. Wird eine Vorlage allerdings auf ein anderes Objekt (z. B. eine ZSQL-Methode) angewandt, so verweisen container und here nicht auf dasselbe Objekt.
modules
Die Sammlung von Python-Modulen, die Vorlagen zur Verf�gung stehen. Weitere Informationen dazu finden Sie im Abschnitt �ber Python-Ausdr�cke.

Dieses Kapitel enth�lt eine Reihe von Beispielen f�r die Verwendung dieser Variablen.

Zeichenkettenausdr�cke

Zeichenkettenausdr�cke erm�glichen die problemlose Verbindung von Pfadausdr�cken und Text. Der gesamte Text nach dem �ffnenden Tag string: wird auf Pfadausdr�cke hin durchsucht. Jedem Pfadausdruck muss ein Dollar-Zeichen ('$') vorangestellt sein:

        "string:Nur Text. Kein Pfad."
        "string:copyright $year, ich."

Besteht der Pfadausdruck aus mehreren Teilen oder muss er vom danach folgenden Text abgetrennt werden, so wird er in geschweifte Klammern ('{}') gesetzt:

        "string:Drei ${Birne}n, bitte."
        "string:Ihr Name ist ${user/getUserName}!"

Achten Sie bei diesem Beispiel darauf, dass der Pfad Birne in geschweifte Klammern gesetzt werden muss, damit Zope ihn nicht mit Birnen verwechselt.

Da sich der Text innerhalb eines Attributwerts befindet, k�nnen Sie doppelte Anf�hrungszeichen nur mit Hilfe der Entit�tssyntax " einf�gen. Kommt im Text ein Dollar-Zeichen vor, so muss es verdoppelt werden ('$$'), weil das einfache Dollar-Zeichen Pfadausdr�cke kennzeichnet:

        "string:Bitte bezahlen Sie $$$dollars_owed"
        "string:Sie sagte: "Hallo Welt.""

Einige komplexe Formatierungsoptionen f�r Zeichenketten (z. B. Suchen und Ersetzen oder Umwandlung in Gro�buchstaben) k�nnen mit Zeichenkettenausdr�cken problemlos umgesetzt werden. Am besten sind hierf�r Python-Ausdr�cke oder Skripte geeignet.

Pfadausdr�cke

Pfadausdr�cke verweisen mit einem URL-�hnlichen Pfad auf Objekte. Ein Pfad beschreibt den Weg von einem Objekt zu einem anderen Objekt. Alle Pfade beginnen mit einem bekannten Objekt (z. B. einer integrierten Variable, einer Wiederholungsvariable oder einer benutzerdefinierten Variable) und gehen von dort aus zum gew�nschten Objekt. Einige Beispiele f�r Pfadausdr�cke:

        template/title
        container/files/objectValues
        user/getUserName
        container/master.html/macros/header
        request/form/address
        root/standard_look_and_feel.html

Pfadausdr�cke erm�glichen den Wechsel von einem Objekt zu seinen Unterobjekten einschlie�lich der Eigenschaften und Methoden. Auch die Akquisition kann in Pfadausdr�cken verwendet werden. Weitere Informationen zur Akquisition und Pfaddurchquerung finden Sie im Abschnitt "Skripte aus dem Internet aufrufen" in Kapitel 10, "Zope-Scripting f�r Fortgeschrittene"; und in Kapitel 7, "Benutzer und Sicherheit", erfahren Sie mehr �ber die Objektzugriffssteuerung.

Alternative Pfade

Der Pfad template/title besteht immer, wenn die Vorlage verwendet wird, kann allerdings eine leere Zeichenkette sein. Andere Pfade, z. B. request/form/x, gibt es bei bestimmten Umsetzungen der Schablone nicht. In diesem Fall tritt ein Fehler auf, wenn Zope den Pfadausdruck auswertet.

Gibt es einen bestimmten Pfad nicht, so k�nnen Sie einen Ersatzpfad oder -wert einrichten, der statt dieses Pfades verwendet werden soll. Existiert z. B. request/form/x nicht, so k�nnen Sie here/x als Alternative festlegen. Um einen alternativen Pfad zu definieren, geben Sie eine Liste von Pfaden an, die nach Priorit�t geordnet und durch senkrechte Striche ('|') voneinander abgetrennt werden:

          

Header

Als letztes Element einer Liste alternativer Pfade sind besonders die Variablen nothing und default sinnvoll. In diesem Fall teilt z. B. default der Anweisung tal:content mit, dass der Blindinhalt unver�ndert bleiben soll. Andere TAL-Anweisungen interpretieren default und nothing anders. Weitere Informationen hierzu finden Sie in Anhang C, "Zope-Page-Templates-Referenz".

Der letzte Teil eines Alternativpfadausdrucks kann auch ein Nicht-Pfadausdruck sein, zum Beispiel:

          

Alter

Existiert in diesem Beispiel der Pfad request/form/age nicht, so ist der Wert die Zahl 18. Dieses Formular erm�glicht die Angabe von Standardwerten, die nicht als Pfade ausgedr�ckt werden k�nnen. Beachten Sie, dass Sie Nicht-Pfadausdr�cke nur als letzte Alternative verwenden k�nnen.

Mit dem Ausdruckstyppr�fix exists kann direkt gepr�ft werden, ob ein Pfad existiert. Weitere Informationen zu exists-Ausdr�cken finden Sie im Abschnitt "exists-Ausdr�cke" weiter unten in diesem Kapitel.

not-Ausdr�cke

Mit not-Ausdr�cken k�nnen Sie den Wert anderer Ausdr�cke negieren. Hierzu ein Beispiel:

        

Hier sind keine Objekte enthalten.

Ist der Ausdruck, auf den ein not-Ausdruck angewendet wird, falsch, so gibt der not-Ausdruck true zur�ck, und umgekehrt. In Zope werden nicht vorhandene Variablen, null, leere Zeichenketten, leere Folgen, nothing und None als falsch gewertet, alles andere als wahr.

In Verbindung mit Python-Ausdr�cken wird normalerweise kein not-Ausdruck verwendet, sondern das Python-Schl�sselwort not.

nocall-Ausdr�cke

Ein gew�hnlicher Pfadausdruck versucht das Objekt, das er abruft, umzusetzen. Falls das Objekt eine Funktion, ein Skript, eine Methode oder ein anderes ausf�hrbares Objekt ist, bedeutet dies, dass der Ausdruck als das Ergebnis des Objektaufrufs ausgewertet wird. Dies ist zwar meist das gew�nschte Ergebnis, aber nicht immer. M�chte man z. B. ein DTML-Dokument in eine Variable einf�gen, um auf seine Eigenschaften verweisen zu k�nnen, so kann man daf�r keinen normalen Pfadausdruck verwenden, da dieser das Dokument in eine Zeichenkette umwandelt.

Setzt man einem Pfad das Ausdruckstyppr�fix nocall: voran, so wird die Umsetzung unterbunden und nur das Objekt abgerufen. Hierzu ein Beispiel:

        
        ID: Titel

Dieser Ausdruckstyp ist auch n�tzlich, wenn Sie eine Variable definieren m�chten, die zur Weiterverwendung in einem Python-Ausdruck eine Funktion oder Klasse aus einem Modul enthalten soll.

Nicht nur auf Objekten, sondern auch auf Funktionen k�nnen nocall-Ausdr�cke verwendet werden:

        

Dieser Ausdruck definiert die Variable join nicht als Ergebnis eines Funktionsaufrufs, sondern als Funktion ('string.join').

exists-Ausdr�cke

Ein exists-Ausdruck ist dann wahr, wenn sein Pfad existiert; ansonsten ist er falsch. Das folgende Beispiel zeigt eine M�glichkeit, eine Fehlermeldung nur dann auszugeben, wenn sie in der Anfrage �bergeben wird:

        

Fehler!

Mit einem exists-Ausdruck erzielen Sie dasselbe Ergebnis auf einfachere Art:

        

Fehler!

Auch eine Kombination von not- und exists-Ausdr�cken ist m�glich:

        

Geben Sie bitte eine Zahl zwischen 0 und 5 ein.

Beachten Sie, dass der Ausdruck "not:request/form/number" in diesem Beispiel nicht verwendet werden kann, da er wahr ist, falls die Variable number existiert und den Wert null hat.

Python-Ausdr�cke

Python ist eine einfache und ausdrucksstarke Programmiersprache. Falls Sie bisher noch nicht damit gearbeitet haben, sollten Sie eine der hervorragenden Einf�hrungen lesen, die Sie auf der Python-Website finden.

Ein Python-Ausdruck f�r Seitenvorlagen kann alles enthalten, was Python als einen Ausdruck erkennt. Nicht verwendet werden d�rfen Anweisungen wie zum Beispiel if und while. Au�erdem erzwingt Zope einige sicherheitsrelevante Einschr�nkungen, um den Zugriff auf gesch�tzte Informationen, die �nderung gesicherter Daten und die Einf�hrung problematischer Verfahren (z. B. Endlosschleifen) zu verhindern. Weitere Informationen zu Sicherheitsrestriktionen f�r Python finden Sie in Kapitel 10, "Zope-Scripting f�r Fortgeschrittene".

Vergleich

In einigen F�llen sind Python-Ausdr�cke fast unumgehbar. Hierzu geh�rt z. B. die Anweisung tal:condition. Normalerweise vergleicht man zwei Zeichenketten oder Zahlen, und dies ist nur mit Python-Ausdr�cken m�glich. Sie k�nnen die Vergleichsoperatoren < (kleiner als), > (gr��er als), == (ist gleich) und != (ist nicht gleich) sowie die Booleschen Operatoren and, not und or verwenden. Beispiele:

          

1: Name

Dieses Beispiel durchl�uft eine Sammlung von Objekten mit einer Schleife und pr�ft dabei das Attribut type der einzelnen Objekte.

Manchmal m�chte man innerhalb einer Anweisung anhand einer oder mehrerer Bedingungen verschiedene Werte w�hlen. Dies ist mit der Funktion test m�glich:

          Sie 
                sind angemeldet als
                Name
              

Die Funktion test funktioniert wie eine if/then/else-Anweisung. Weitere Informationen zu dieser Funktion finden Sie in Anhang A, "DTML-Referenz". Das folgende Beispiel veranschaulicht die Verwendung der Funktion test:

          
                

Ohne die Funktion test m�ssten Sie hier zwei tr-Elemente mit jeweils unterschiedlichen Bedingungen schreiben: eine f�r gerade Zeilen und eine f�r ungerade Zeilen.

Weitere Ausdruckstypen

Auch andere Ausdruckstypen k�nnen in einem Python-Ausdruck verwendet werden. Jedem Ausdruckstyp entspricht eine gleichnamige Funktion: path(), string(), exists() und nocall(). Somit kann man Ausdr�cke wie die folgenden schreiben:

          "python:path('here/%s/thing' % foldername)"
          "python:path(string('here/$foldername/thing'))"
          "python:path('request/form/x') or default"

Das letzte Beispiel hat eine etwas andere Bedeutung als der Pfadausdruck "request/form/x | default", da es den Standardtext verwendet, falls "request/form/x" nicht existiert oder falsch ist.

Auf Zope-Objekte zugreifen

Zope ist vor allem auch deshalb so leistungsf�hig, weil es spezialisierte Objekte miteinander verbindet. Seitenvorlagen k�nnen Skripte, SQL-Methoden, Kataloge und benutzerdefinierte Inhaltsobjekte verwenden. Um diese Objekte nutzen zu k�nnen, m�ssen Sie wissen, wie Sie in Seitenvorlagen auf sie zugreifen k�nnen.

Objekteigenschaften sind normalerweise Attribute. Daher ruft man den Titel einer Vorlage mit dem Ausdruck "template.title" ab. Die meisten Zope-Objekte unterst�tzen die Akquisition, die den Zugriff auf Attribute von Elternobjekten erm�glicht. Dies bedeutet, dass der Python-Ausdruck "here.Control_Panel" das Objekt Systemsteuerung aus dem Wurzelordner erwirbt. Objektmethoden sind Attribute, z. B. "here.objectIds" und "request.set". Auf Objekte in einem Ordner kann man als Attribute dieses Ordners zugreifen. Allerdings sind ihre Namen h�ufig keine zul�ssigen Python-Bezeichner, sodass man nicht die normale Notation verwenden kann. So ist z. B. dieser Python-Ausdruck nicht zul�ssig:

          "python:here.pinguin.gif"'. 

Stattdessen m�ssen Sie die folgende Notation verwenden:

          "python:getattr(here, 'pinguin.gif')"

Dies liegt daran, dass Python Attributnamen, die Punkte enthalten, nicht unterst�tzt.

Einige Objekte, z. B. request, modules und Zope-Ordner, unterst�tzten den Python-Elementzugriff:

          request['URL']
          modules['math']
          here['thing']

Wenn Sie den Elementzugriff auf einen Ordner anwenden, versucht er nicht, den Namen zu akquirieren, wird also nur dann erfolgreich durchgef�hrt, wenn der Ordner tats�chlich ein Objekt mit dem angegebenen Namen enth�lt.

In anderen Kapiteln wurde bereits gezeigt, dass Sie bei Pfadausdr�cken Einzelheiten des Weges von einem Objekt zum n�chsten ignorieren k�nnen. Zope versucht zuerst einen Attributzugriff, dann einen Elementzugriff. Anstatt

          "python:getattr(here.images, 'pinguin.gif')"

k�nnen Sie auch die folgende Schreibweise verwenden:

          "here/images/pinguin.gif"

ebenso auch

          "request/form/x" 

an Stelle von:

          "python:request.form['x']"

Der Nachteil ist, dass die Angabe dieser Einzelheiten bei Pfadausdr�cken nicht m�glich ist. Haben Sie z. B. eine Formularvariable namens "get", so m�ssen Sie

          "python:request.form['get']"

schreiben, da der Pfadausdruck

          "request/form/get" 

als die Methode "get" des Formularw�rterbuches ausgewertet wird.

Mit der Funktion path() k�nnen Sie, wie oben beschrieben, Pfadausdr�cke innerhalb von Python-Ausdr�cken verwenden.

Mit Skripten arbeiten

Skriptobjekte werden h�ufig daf�r verwendet, die Anwendungslogik und eine komplexe Datenbearbeitung zu kapseln. Schreiben Sie viele TAL-Anweisungen, die komplizierte Ausdr�cke enthalten, so sollten Sie auf jeden Fall erw�gen, stattdessen ein Skript zu verwenden. Bereitet es Ihnen Schwierigkeiten, Ihre Vorlagenanweisungen und -ausdr�cke zu durchschauen, so sollten Sie die Vorlage vereinfachen und f�r die komplexen Bereiche Skripte verwenden.

F�r jedes Skript gibt es eine Parameterliste, die dem Skript bei dessen Aufruf �bergeben wird. Ist diese Liste leer, so k�nnen Sie das Skript dennoch verwenden, indem Sie einen Pfadausdruck angeben. Anderenfalls m�ssen Sie das Argument mit Hilfe eines Python-Ausdrucks bereitstellen:

          "python:here.myscript(1, 2)"
          "python:here.myscript('arg', foo=request.form['x'])"

Geben Sie aus einem Skript mehr als ein Datenelement an eine Seitenvorlage zur�ck, so ist die R�ckgabe in einem W�rterbuch sinnvoll, denn dabei k�nnen Sie eine Variable definieren, die alle Daten enth�lt, und �ber Pfadausdr�cke auf die einzelnen Daten verweisen. Nehmen wir z. B. an, dass das Skript getPerson ein W�rterbuch mit den Schl�sseln name und age zur�ckgibt:

          
          Name ist 30 Jahre alt.

Nat�rlich k�nnen auch Zope-Objekte und Python-Listen zur�ckgegeben werden.

DTML aufrufen

Im Gegensatz zu Skripten haben DTML-Methoden und -Dokumente keine ausdr�ckliche Parameterliste. Stattdessen m�ssen ihnen ein Client, eine Zuordnung und Schl�sselwortargumente �bergeben werden. Anhand dieser Parameter erstellen sie dann einen Namensraum. Weitere Informationen zu ausdr�cklichen DTML-Aufrufen finden Sie in Kapitel 7.

Wenn Zope ein DTML-Objekt �ber das Internet ver�ffentlicht, �bergibt es den Inhalt des Objekts als Client und die Anfrage (REQUEST) als Zuordnung. Wenn ein DTML-Objekt ein anderes DTML-Objekt aufruft, �bergibt es keinen Client und als Zuordnung seinen eigenen Namensraum.

Falls Sie ein DTML-Objekt �ber einen Pfadausdruck umsetzen, �bergibt es einen Namensraum, der request, here und die Variablen der Vorlage bereits enth�lt. Dies bedeutet, dass das DTML-Objekt nicht nur dieselben Namen wie bei einer Ver�ffentlichung im Kontext der Vorlage verwenden kann, sondern auch die in der Vorlage definierten Variablennamen.

Python-Module

Die Programmiersprache Python enth�lt eine Vielzahl von Modulen, die Python-Programme flexibel und vielseitig machen. Jedes Modul ist eine Sammlung von Python-Funktionen, -Daten und -Klassen, die sich auf einen einzigen Zweck beziehen, z. B. auf mathematische Berechnungen oder regul�re Ausdr�cke.

Einige Module, darunter "math" und "string", stehen in Python-Ausdr�cken immer zur Verf�gung. So k�nnen Sie zum Beispiel mit "python:math.pi" den Wert von pi aus dem Modul "math" abrufen. Um darauf aus einem Pfadausdruck heraus zuzugreifen, ben�tigen Sie hingegen die Variable modules: "modules/math/pi".

Da das Modul "string"in Python-Ausdr�cken durch die Ausdruckstypfunktion "string" verborgen ist, ben�tigen Sie f�r den Zugriff auf das Modul die Variable modules. Dabei gibt es zwei M�glichkeiten, auf das Modul zuzugreifen: Entweder direkt in einem Ausdruck, in dem Sie es verwenden, oder, wie im folgenden Beispiel, �ber eine selbst definierte globale Variable.

          tal:define="global mstring modules/string"
          tal:replace="python:mstring.join(slist, ':')"

In der Praxis ist dies selten erforderlich. Meist braucht man sich nicht auf Funktionen im Modul "string" zu st�tzen, sondern kann stattdessen Zeichenkettenmethoden verwenden.

Module k�nnen zu Paketen zusammengefasst werden. Pakete stellen eine einfache M�glichkeit dar, verwandte Module zu organisieren und zu benennen. So werden z. B. die Python-basierten Skripte in Zope als eine Sammlung von Modulen im Unterpaket "PythonScripts" des Zope-Pakets "Products" bereitgestellt. Besonders das in diesem Paket enthaltene Modul "standard" bietet eine Reihe n�tzlicher Formatierungsfunktionen, die im DTML-Tag "var" regelm��ig eingesetzt werden. Der vollst�ndige Name dieses Moduls ist "Products.PythonScripts.standard"; der Zugriff erfolgt demnach mit einer der folgenden Anweisungen:

          tal:define="global pps modules/Products/PythonScripts/standard"
          tal:define="global pps python:modules['Products.PythonScripts.standard']"

Auf die meisten Python-Module kann man nur dann aus Seitenvorlagen, DTML oder Skripten heraus zugreifen, wenn man diese um Zope-spezifische Sicherheitsma�nahmen erweitert. Diese Verfahren k�nnen im Rahmen dieses Buches nicht besprochen werden; sie werden im Zope Developer's Guide n�her erl�utert.

Makros

Bisher haben Sie gesehen, wie Sie einzelnen Web-Seiten mit Seitenvorlagen dynamisches Verhalten hinzuf�gen k�nnen. Dar�ber hinaus erm�glichen Seitenvorlagen die Wiederverwendung von Darstellungselementen auf mehreren Seiten.

Mit Seitenvorlagen k�nnen Sie zum Beispiel eine Site mit einem einheitlichen Look&Feel einrichten: Unabh�ngig vom Inhalt der einzelnen Seiten erhalten alle Seiten identische Header, Footer, Seitenleisten und/oder andere Seitenelemente. Dies ist eine Anforderung, die h�ufig an Websites gestellt wird.

Mit Makros k�nnen Sie Darstellungselemente auf mehreren Seiten wiederverwenden. Makros definieren einen Seitenbereich, der in anderen Seiten wiederverwendet werden kann. Ein Makro kann ebenso gut eine ganze Seite wie ein kleiner Seitenbereich sein, also z. B. ein Header oder Footer. Nachdem Sie in einer Seitenvorlage ein oder mehrere Makros definiert haben, k�nnen Sie diese auch in anderen Seitenvorlagen verwenden.

Makros verwenden

Makros werden mit TAG-Attributen �hnlich den TAL-Anweisungen definiert. Makro-Tag-Attribute werden als METAL-Anweisungen bezeichnet, wobei METAL f�r Macro Expansion Tag Attribute Language steht. Das folgende Beispiel zeigt die Definition eines Makros:

        

Copyright 2001, Foo, Bar und Co. KG

Diese metal:define-macro-Anweisung definiert ein Makro namens "copyright", das aus dem Tag p und seinem Inhalt besteht (einschlie�lich aller darin enthaltenen Tags).

In einer Seitenvorlage definierte Makros werden im Attribut macro der Vorlage gespeichert. Makros aus einer anderen Vorlage k�nnen Sie verwenden, indem Sie �ber das Attribut macros der Seitenvorlage, in der sie definiert sind, auf sie verweisen. Nehmen wir z. B. an, dass das Makro copyright in der Seitenvorlage "master_page" definiert ist. In einer anderen Seitenvorlage wird copyright nun mit dem folgenden Code aufgerufen:

        
Hier folgt das Makro

Wenn Zope diese Seitenvorlage umsetzt, wird das Tag b vollst�ndig durch das Makro ersetzt:

        

Copyright 2001, Foo, Bar und Co. KG

Wird das Makro ge�ndert (z. B. wegen Namens�nderung des Urheberrechtsinhabers), so spiegelt sich diese �nderung in allen Seitenvorlagen wider, die dieses Makro verwenden.

Beachten Sie, dass das Makro durch einen Pfadausdruck mit der Anweisung metal:use-macro angegeben wird. Die Anweisung metal:use-macro ersetzt das Anweisungselement durch das genannte Makro.

Makros im Detail

Die Anweisungen metal:define-macro und metal:use-macro sind recht einfach. Allerdings gibt es einige Feinheiten, die erw�hnt zu werden verdienen.

Der Name eines Makros muss innerhalb der Seitenvorlage, in der es definiert wird, eindeutig sein. Sie k�nnen in einer Vorlage mehrere Makros definieren, doch jedes dieser Makros muss einen anderen Namen haben.

Normalerweise verweist man auf Makros in einer metal:use-macro-Anweisung mit einem Pfadausdruck. Eigentlich kann man aber jeden beliebigen Ausdruckstyp verwenden, wichtig ist nur, dass er ein Makro zur�ckgibt. Hierzu ein Beispiel:

        

Wird durch ein dynamisch ermitteltes Makro ersetzt, das vom Skript getMacro gesucht wird.

Verweist man mit Python-Ausdr�cken auf Makros, so kann man das Makro, das eine Vorlage verwenden soll, dynamisch wechseln.

Das folgende Beispiel veranschaulicht, wie die Anweisung metal:use-macro zusammen mit der Variable default verwendet wird:

        

Dieser Inhalt bleibt erhalten - es wird kein Makro verwendet.

Dieser Code f�hrt zu demselben Ergebnis wie die Verwendung von default mit tal:content und tal:replace; das Anweisungselement bleibt unver�ndert.

Der Versuch, die Variable nothing mit metal:use-macro zu verwenden, l�st einen Fehler aus, da nothing kein Makro ist. Falls Sie nothing verwenden m�chten, um ein Makro bedingt einzuf�gen, sollten Sie stattdessen die Anweisung metal:use-macro in eine tal:condition-Anweisung einschlie�en.

Bei der Umsetzung von Vorlagen behandelt Zope zuerst Makros und wertet dann TAL-Ausdr�cke aus. Betrachten Sie z. B. das folgende Makro:

        

Titel der Vorlage

Dieses Makro f�gt den Titel der Vorlage ein, in der das Makro verwendet wird, nicht den der Vorlage, in der es definiert wird. Anders ausgedr�ckt: Verwendet man ein Makro, so ist das dasselbe, wie wenn man das Makro in eine Vorlage kopiert und diese dann umsetzt.

Wenn Sie die Option Expand macros when editing in der Ansicht Edit einer Seitenvorlage aktivieren, werden alle Makros, die Sie verwenden, im Quellcode der Seitenvorlage vollst�ndig angezeigt. Dies ist das Standardverhalten von Zope und in aller Regel auch das gew�nschte Verhalten, da man so eine vollst�ndige und g�ltige Seite bearbeiten kann. Manchmal ist es jedoch komfortabler, die Makros w�hrend der Bearbeitung nicht vollst�ndig anzuzeigen. Dies ist insbesondere dann der Fall, wenn man keinen WYSISYG-Editor verwendet, sondern im ZMI arbeitet. Um Makros nicht vollst�ndig anzuzeigen, deaktiviert man einfach die entsprechende Option.

Slots

Noch n�tzlicher werden Makros dadurch, dass man ein Makro bei seinem Einsatz teilweise �berschreiben kann. Hierf�r definieren Sie so genannte Slots im Makro, die Sie dann, wenn Sie die Vorlage verwenden, f�llen k�nnen. Betrachten Sie z. B. das folgende Makro f�r eine Seitenleiste:

        

Links

Dieses Makro ist an sich zwar gut, erm�glicht aber keine Abweichungen. M�chten Sie nun in der Seitenleiste zus�tzliche Informationen bereitstellen, so besteht eine L�sungsm�glichkeit darin, Slots zu definieren:

        

Links

Mit diesem Makro k�nnen Sie den Slot folgenderma�en f�llen:

        

Beachten Sie auch unsere Sonderaktionen.

Wenn Sie diese Vorlage umsetzen, enth�lt die Seitenleiste die Zusatzinformation, die Sie im Slot bereitstellen:

        

Links

Beachten Sie auch unsereSonderaktionen.

Achten Sie darauf, wie das Element span, das den Slot definiert, durch das Element b ersetzt wird, das den Slot f�llt.

Anpassung der Standarddarstellung

Normalerweise dienen Slots daf�r, eine Standarddarstellung bereitzustellen, die dann angepasst werden kann. Im obigen Beispiel besteht die Definition des Slots einfach aus einem leeren span-Element. Allerdings k�nnen Sie in einer Slot-Definition auch eine Standarddarstellung angeben. Betrachten Sie z. B. die folgende Version des Makros f�r die Seitenleiste:

        

Links

  • Home
  • Produkte
  • Kundendienst
  • Kontakt

Jetzt k�nnen alle Bestandteile der Seitenleiste individuell angepasst werden. Sie k�nnen den Slot links so ausf�llen, dass die Seitenleisten-Links neu definiert werden. F�llen Sie ihn jedoch nicht aus, so werden in diesem Slot die Standard-Links angezeigt.

Mit demselben Verfahren k�nnen Sie auch Slots in Slots definieren und damit die Standarddarstellung durch eine detailliertere Ausf�hrung �berschreiben. Hier sehen Sie noch einmal das Makro f�r die Seitenleiste, wobei diesmal jedoch innerhalb der Slots weitere Slots definiert werden:

        

Links

  • Home
  • Produketes
  • Kundendienst
  • Kontakt

M�chten Sie die Links in der Seitenleiste anpassen, so k�nnen Sie entweder den Slot links so f�llen, dass er die Links vollst�ndig �berschreibt, oder den Slot additional_links so f�llen, dass nach den Standard-Links noch weitere Links eingef�gt werden. Slots k�nnen beliebig tief geschachtelt werden.

METAL und TAL kombinieren

METAL- und TAL-Anweisungen k�nnen auf dieselben Elemente angewandt werden:

        

Da METAL-Anweisungen vor TAL-Anweisungen ausgewertet werden, gibt es keine Konflikte. Dieses Beispiel ist auch insofern interessant, als es ein Makro ohne Slots anpasst. Das Makro ruft das Skript getLinks auf, um die Links zu ermitteln. Somit k�nnen Sie die Links Ihrer Site anpassen, indem Sie das Skript getLinks an verschiedenen Speicherorten Ihrer Web Site anpassen.

Nicht immer ist es einfach, das beste Verfahren f�r die Anpassung der Darstellung verschiedener Bereiche einer Site zu finden. Im Allgemeinen empfiehlt es sich, Darstellungselemente mit Slots zu �berschreiben und dynamischen Inhalt mit Skripten bereitzustellen. In manchen F�llen, wie etwa dem oben gezeigten Link-Beispiel, ist nicht klar, ob es sich bei einem Seitenelement um Inhalt oder Darstellung handelt. Skripte sind in diesem Fall wahrscheinlich die flexiblere L�sung, besonders wenn die Site Link-Inhaltsobjekte enth�lt.

Eine Seite als Makro

Nicht nur einzelne Darstellungselemente, die von mehreren Seiten verwendet werden, k�nnen mit Makros definiert werden, sondern auch ganze Seiten. Erm�glicht wird dies durch Slots. Das folgende Beispiel zeigt ein Makro, das eine ganze Seite definiert:

        
          
            Der Titel
          

          
            

Titel

Dies ist der Rumpf.

Copyright 2001 Fluffy Enterprises

Dieses Makro definiert eine Seite mit drei Slots: headline, body und footer. Achten Sie darauf, dass der Slot headline eine TAL-Anweisung enth�lt, die den Inhalt der �berschrift dynamisch ermittelt.

Dieses Makro k�nnen Sie in Vorlagen f�r verschiedene Arten von Inhalt oder f�r verschiedene Teile einer Site verwenden. In einer Vorlage f�r Nachrichten k�nnte das Makro zum Beispiel folgenderma�en eingesetzt werden:

       

         

Pressemeldung: �berschrift

Hier folgt die Meldung selbst.

Diese Vorlage definiert den Slot headline neu, und zwar so, dass er den Text "Pressemeldung" enth�lt und die Methode getHeadline auf dem aktuellen Objekt aufruft. Au�erdem definiert sie den Slot body so, dass er die Methode getBody auf dem aktuellen Objekt aufruft.

Dieses Verfahren ist deshalb so leistungsf�hig, weil damit bei einer �nderung des Makros page automatisch auch die Vorlage f�r die Pressemeldung aktualisiert wird. Sie k�nnen z. B. den body der Seite in eine Tabelle einf�gen und links davon eine Seitenleiste einrichten; die Vorlage f�r die Pressemeldung verwendet dann automatisch diese neuen Darstellungselemente.

Damit bietet dieses Verfahren weitaus flexiblere M�glichkeiten, das Look&Feel einer Seite zu steuern, als die DTML-L�sung mit standard_html_header und standard_html_footer. Im Wurzelordner von Zope finden Sie eine Seitenvorlage namens standard_template.pt, die ein Seitenmakro mit einem head- und einem body-Slot enth�lt. Das folgende Beispiel veranschaulicht eine M�glichkeit, dieses Makro in einer Vorlage zu verwenden:

        
          

Titel

Hier folgt der Textk�rper.

Das Makro standard_template.pt wird �hnlich verwendet wie andere Seitenmakros. Eine Besonderheit stellt lediglich der Pfad zum Makro dar. Im obigen Beispiel beginnt der Pfad mit here. Dies bedeutet, dass Zope mit Hilfe der Akquisition nach dem Objekt standard_template.pt sucht, wobei es bei dem Objekt zu suchen beginnt, auf das die Vorlage angewandt wird. Dadurch k�nnen Sie die Darstellung von Vorlagen anpassen, indem Sie an verschiedenen Speicherorten individuell angepasste standard_template.pt-Objekte erstellen. Dieses Verfahren entspricht also dem Anpassen der Darstellung durch �berschreiben von standard_html_header und standard_html_footer an einzelnen Stellen einer Web Site. Bei standard_template.pt stehen Ihnen allerdings mehr M�glichkeiten zur Verf�gung. Sie k�nnen den Pfad zum Makro nicht nur mit here beginnen, sondern auch mit root oder container. Beginnt der Pfad mit root, so erhalten Sie immer die Standardvorlage, die sich im Wurzelordner befindet. Beginnt der Pfad mit container, so sucht Zope die Standardvorlage mit Hilfe der Akquisition und beginnt dabei in dem Ordner, in dem die Vorlage definiert ist. Dies erlaubt zwar die Anpassung des Look&Feel von Vorlagen, nicht aber die Anpassung des Look&Feel unterschiedlicher Objekte anhand ihres Speicherorts innerhalb der Site.

Vorlagen zwischenspeichern

Normalerweise werden Seitenvorlagen zwar relativ schnell umgesetzt, manchmal aber nicht schnell genug. Bei Seiten, auf die h�ufig zugegriffen wird oder bei denen der Seitenaufbau lange dauert, lohnt es sich, eine h�here Geschwindigkeit auf Kosten des dynamischen Verhaltens zu erzielen. Zu erreichen ist dieser Kompromiss durch Puffern, d. h. Zwischenspeichern im Cache. Weitere Informationen zum Puffern finden Sie im Abschnitt "Pufferung zur Leistungssteigerung" in Kapitel 3, "Verwendung grundlegender Zope-Objekte".

Seitenvorlagen k�nnen genau wie andere Objekte mit einem Cache-Manager gepuffert werden. Um eine Seitenvorlage zu puffern, m�ssen Sie sie mit einem Cache-Manager verbinden. Hierf�r w�hlen Sie entweder in der Ansicht Cache der betreffenden Seitenvorlage den Cache-Manager oder in der Ansicht Associate des Cache-Managers die gew�nschte Seitenvorlage.

Das folgende Beispiel veranschaulicht das Puffern einer Seitenvorlage. Zuerst erstellen Sie den Python-basierten Skriptnamen long.py mit dem folgenden Inhalt:

      ## Script (Python) "long.py"
      ##
      for i in range(500):
        for j in range(500):
          for k in range(5):
            pass
      return 'Done'

Der Zweck dieses Skript besteht darin, viel Ausf�hrungszeit in Anspruch zu nehmen. Im n�chsten Schritt legen Sie eine Seitenvorlage an, die dieses Skript verwendet; zum Beispiel:

      
        
          

results

Wenn Sie sich diese Seite nun ansehen, werden Sie feststellen, dass ihre Umsetzung einige Zeit dauert. Als N�chstes werden wir die Umsetzung durch Pufferung erheblich beschleunigen. Falls Sie noch keinen Ram-Cache-Manager haben, erstellen Sie ihn jetzt, und zwar unbedingt entweder in demselben Ordner, in dem sich auch die Seitenvorlage befindet, oder auf einer h�heren Ebene. Gehen Sie zur Ansicht Cache der Seitenvorlage, w�hlen Sie dort den Ram-Cache-Manager, den Sie gerade erstellt haben, und klicken Sie Save Changes an. Anschlie�end klicken Sie den Link Cache Settings an, um zu den Konfigurationseinstellungen des Ram-Cache-Managers zu gelangen. In der Standardeinstellung speichert der Cache Objekte f�r eine Stunde (3600 Sekunden). Diesen Zeitraum sollten Sie an Ihre Anwendung anpassen. Kehren Sie nun zur Seitenvorlage zur�ck. Nach wie vor dauert es einige Zeit, bis die Vorlage umgesetzt wird. Wenn Sie die Seite nun jedoch erneut laden, wird sie sofort umgesetzt. Sie k�nnen die Seite neu laden, so oft Sie m�chten; sie wird immer sofort umgesetzt, da die Seite nun im Cache gespeichert ist.

�ndern Sie die Seitenvorlage, so wird sie aus dem Cache entfernt. Wenn Sie sie dann erneut aufrufen, dauert die Umsetzung wieder einige Zeit. Da sie dabei aber im Cache gespeichert wird, wird sie bei allen folgenden Aufrufen wieder schnell aufgebaut.

Das Puffern ist ein einfaches, aber leistungsstarkes Verfahren, um die Leistung zu steigern. Es ist keine Hexerei, steigert die Geschwindigkeit aber betr�chtlich. Bei Anwendungen, bei denen die Leistung eine wichtige Rolle spielt, lohnt sich das Puffern auf jeden Fall.

Hilfprogramme f�r Seitenvorlagen

Zope-Seitenvorlagen sind leistungsstark, aber einfach. Im Gegensatz zu DTML bieten Seitenvorlagen kaum Hilfsmittel f�r die Stapelung, das Anlegen von B�umen, Sortieren usw. Die Erfinder der Seitenvorlagen wollten diese einfach halten. Allerdings vermisst man doch einige der integrierten Funktionen, die DTML bietet. Um diese L�cke zu schlie�en, umfasst Zope Hilfsprogramme, die die Seitenvorlagen verbessern sollen.

Gro�e Informationsmengen stapeln

Wenn ein Anwender eine Datenbank abfragt und Hunderte von Ergebnissen erh�lt, so ist es h�ufig sinnvoller, diese Ergebnisse auf mehrere Seiten zu verteilen (z. B. 20 Ergebnisse pro Seite), als alle Ergebnisse auf einer einzigen Seite auszugeben. Das Zerlegen gro�er Listen in mehrere kleine wird als Stapelung bezeichnet.

Im Gegensatz zu DTML, bei dem die Stapelung direkt in die Programmiersprache integriert ist, unterst�tzen Seitenvorlagen diese durch ein besonderes Objekt namens Batch, das sich im Hilfsmodul ZTUtils befindet. Weitere Informationen zu dem Python-Modul ZTUtils finden Sie im Anhang B, "API-Referenz".

Das folgende einfache Beispiel zeigt, wie ein Batch-Objekt erstellt wird:

        

Dieses Beispiel setzt eine Liste mit 10 Elementen um (in diesem Fall die Zahlen von 0 bis 9). Das Objekt Batch zerschneidet eine lange Liste in Gruppen oder Batches. In diesem Fall teilt es eine aus hundert Elementen bestehende Liste in Gruppen zu je zehn Elementen.

Um eine Gruppe von zehn Elementen anzuzeigen, �bergeben Sie eine andere Anfangszahl:

        
        
          
            Der Titel
          
          

          

zur�ck weiter

Dieses Beispiel iteriert �ber Ergebnisgruppen aus der ZSQL-Methode getEmployees. Es zeichnet die Links zur�ck und weiter, um das Bl�ttern durch die Ergebnisgruppen zu erm�glichen.

Sehen Sie sich die Anweisung tal:define im Element body etwas genauer an. Sie definiert mehrere Batch-Variablen. Die Variable employees ist eine m�glicherweise lange Liste von employee-Objekten, die von der ZSQL-Methode getEmployees zur�ckgegeben wird. Die zweite Variable, start, ist entweder auf den Wert von request/start oder, falls die Anfrage keine start-Variable enth�lt, auf null gesetzt. Die Variable start verfolgt, an welcher Stelle der Angestelltenliste Sie sich gerade befinden. Die Variable batch ist eine Gruppe von zehn Elementen aus der Angestelltenliste. Die Gruppe beginnt an der von der Variable start angegebenen Position. Die Variablen previous und next verweisen auf die vorhergehende und die folgende Gruppe (soweit vorhanden). Da alle diese Variablen im Element body definiert sind, stehen sie allen Elementen im Body zur Verf�gung.

Sehen wir uns nun die Navigations-Links an. Diese erstellen Hyperlinks, die das Bl�ttern zur vorhergehenden und zur folgenden Gruppe erm�glichen. Die Anweisung tal:condition pr�ft zuerst, ob es eine vorhergehende und eine folgende Gruppe gibt. Ist dies der Fall, so wird der Link dargestellt, anderenfalls nicht. Die Anweisung tal:attributes erstellt einen Link zur vorhergehenden und zur folgenden Gruppe. Der Link besteht einfach aus dem URL der aktuellen Seite ('request/URL0') und einer Anfragezeichenkette, die den Anfangsindex der Gruppe angibt. Beginnt die aktuelle Gruppe zum Beispiel mit dem Index 10, so muss die vorhergehende Gruppe mit dem Index 0 beginnen. Die Variable first einer Gruppe gibt deren Anfangsindex an, in diesem Fall ist previous.start also 0.

Sie brauchen nicht alle Einzelheiten dieses Beispiels zu verstehen. Kopieren Sie es einfach oder verwenden Sie ein vom Z Search Interface erstelltes Stapelungsbeispiel. Wenn Sie sp�ter komplexere Batch-Aufgaben l�sen m�chten, k�nnen Sie mit diesem Beispielcode experimentieren. In Anhang B, "API-Referenz" finden Sie weitere Informationen zum Modul ZTUtils sowie zu Batch-Objekten.

Verschiedene Hilfsprogramme

Zope bietet eine Reihe von Python-Modulen, die die Arbeit mit Seitenvorlagen erleichtern. Die Module string, math und random k�nnen in Python-Ausdr�cken f�r die Formatierung von Zeichenketten, f�r mathematische Funktionen und f�r die Erzeugung von Zufallszahlen verwendet werden. Diese Module stehen in Python-basierten und DTML-Skripten gleicherma�en zur Verf�gung. Weitere Informationen dazu finden Sie in Anhang B, "API-Referenz".

Das Modul Products.PythonScripts.standard soll Hilfsprogramme f�r Python-basierte Skripte bereitstellen, ist aber auch bei der Arbeit mit Seitenvorlagen sinnvoll. Es umfasst verschiedene Funktionen f�r die Formatierung von Zeichenketten und Zahlen. Weitere Informationen dazu finden Sie in Anhang B, "API-Referenz".

Wie in diesem Kapitel bereits erw�hnt wurde, stellt das Modul sequence die n�tzliche Funktion sort bereit. Einzelheiten dazu finden Sie in Anhang B, "API-Referenz".

Das Modul AccessControl enth�lt eine Funktion und eine Klasse, die Sie f�r die Pr�fung des Zugriffs sowie f�r das Abrufen berechtigter Anwender ben�tigen. Weitere Informationen dazu finden Sie in Anhang B, "API-Referenz".

Zusammenfassung

Dieses Kapitel behandelt die Einzelheiten von Seitenvorlagen, und stiftet zun�chst vielleicht vor allem Verwirrung. Aber keine Sorge: Um Seitenvorlagen effizient einzusetzen, brauchen Sie nicht alles zu wissen, was hier angesprochen wurde. Wichtig sind die verschiedenen Pfadtypen und Makros. Die �brigen Informationen, die komplizierteren Aspekte, die Sie in diesem Kapitel kennen gelernt haben, k�nnen Sie auch sp�ter jeder Zeit nachlesen, wenn Sie sie tats�chlich ben�tigen. Doch es ist beruhigend, zu wissen, dass Ihnen dann, wenn Sie soweit sind, mit Seitenvorlagen beeindruckende M�glichkeiten offenstehen.