Hallo tjuXx!
Ganz so klein ist das Beispiel jetzt doch nicht geworden. Ich habe ein paar Dinge ausprobiert und versucht eine Best-Practice auszuarbeiten. Außerdem habe ich das Beispiel mit ein paar Goodies bestückt, die vielleicht nicht uninteressant sind.
Es gibt mehrere Möglichkeiten, Vorlagen miteinander zu kombinieren.
Eine davon ist die ``#include``-Anweisung in der Cheetah-Vorlage selbst. Mit ``#include`` kann man andere Cheetah-Vorlagen in die Vorlage importieren. Die importierte Vorlage wird wie ein Teil der aktuellen Vorlage behandelt. Das heißt, dass die dynamischen Bereiche der importierten Vorlage so ausgeführt werden, als ob sie direkt in der aktuellen Vorlage stehen würden.
Diesen Mechanismus verwende ich gerne für Teile, die ich gerne dynamisch anpassen möchte, ohne die Hauptvorlage dafür ändern zu müssen. Z.B. für den Header oder den Footer.
Die Verwendung von ``#include`` ist ziemlich einfach. Nach ``#include`` gibt man den Pfad zur einzubindenden Vorlage, relativ zum Anwendungsordner an. Der Anwendungsordner ist der Ordner, in dem sich das Programm befindet, welches die Vorlagen rendert und anzeigt. z.B. ``#include "templates/pagetemplate/header.tmpl"``
Weiters kann man in eine Vorlage direkt dynamischen Content einbinden. Man kann also von der Anwendung HTML erzeugen lassen, der in die Vorlage "dynamisch" eingebunden wird. Das Einbinden von dynamischen Werten passiert in Cheetah-Vorlagen hauptsächlich über das "$"-Zeichen, gefolgt von einem Namen eines Python-Objektes das Text zurück liefern kann. Das kann z.B. der Name einer Variable oder einer Funktion sein.
Interessant dabei ist, dass es sich auch um eine Instanz einer Cheetah-Vorlage handeln kann, die vom Programm an die Vorlage übergeben wurde. Z.B: ``$mainnav`` oder ``$site_title - $page_title``
Dann gibt es noch die Vererbung selbst. In der Hauptvorlage werden Bereiche markiert, die von einer (ich nenne sie jetzt einfach mal so) Untervorlage überschrieben werden können.
In der Hauptvorlage kann man Bereiche z.B. mit ``#block`` markieren. Gibt es in der Untervorlage ebenfalls einen solchen Bereich, dann überschreibt dieser den Bereich der Hauptvorlage an der dort markierten Stelle.
Man kann auch Klassenattribute (mit ``#attr``) erstellen, diese in der Untervorlage überschreiben und in der Hauptvorlage an den verschiedensten Stellen verwenden. Allerdings ist das nicht so ideal, da es hier Probleme mit Unicode gibt. Deshalb habe ich seit einiger Zeit auf die Verwendung von ``#def`` umgestellt. Die Verwendung ist ähnlich einfach wie die Verwendung von ``#attr``.
Statt ``#attr $name = "Ein Text"`` verwende ich jetzt ``#def $name: Ein Text mit Umlauten (ÖÄÜ)``. Nur so nebenbei bemerkt: Ich verwende in meinen Projekten ``gettext`` um die Anwendungen in mehrere Sprachen zu übersetzen. Das lässt sich auf diese Art ziemlich einfach in die Vorlagen integrieren. Ein zu übersetzender Text wird mit ``$_()`` markiert (z.B. so: ``#def $name: $_("Hallo Welt")``). Ein kleines Skript erstellt aus allen Cheetah-Vorlagen Python-Module, dann werden die markierten Texte per ``gettext`` herausgeholt und in eine POT-Datei geschrieben. Danach werden die temporär erstellten Python-Module wieder gelöscht.

Das funktioniert wirklich wunderbar.

Und jetzt zurück zur Vererbung.
Soll eine Untervorlage von einer Hauptvorlage erben, dann wird dies mit ``#extends`` eingeleitet. Als Parameter wird, wie bei ``import`` der Name des Paketes und/oder Modules übergeben. Die Hauptvorlage kann mit dem Kommandozeilenprogramm ``cheetah`` zu einem Python-Modul kompiliert werden. Man kann die Hauptvorlage aber auch im Programm selbst kompilieren lassen. Zuerst wird mit ``Cheetah.Template.Template.compile()`` die Hauptvorlage gerendert. Danach kann man die damit erstellte Klasse mit ``.subclass()`` um die Untervorlage erweitern. Damit das funktioniert, muss man beim Aufruf von ``.compile()`` nur auch den Modulnamen (moduleName = "...") übergeben, der in der Untervorlage mit
``#extends <modulname>`` angegeben wird. Das ist deshalb wichtig, weil die Hauptvorlage nicht als Python-Modul direkt über das Dateisystem zur Verfügung steht. Wie das alles funktioniert, habe ich ins Beispiel mit eingebaut.
Und jetzt noch zu einem Punkt, den ich auch ins Beispiel eingebaut habe --> die Verwendung von Unicode als Basis.
Über die INI-Datei habe ich CherryPy so eingestellt, dass jeder Unicode-String, der von den Request-Handlern zurück gegeben wird, automatisch nach UTF-8 umgewandelt wird. Eine unbedingt notwendige Einstellung, denke ich, wenn man sauber arbeiten möchte.
Und hier das Beispiel:
cpapp.ini
cpapp.py
cpapp_wsgi.py
http_root/
http_root/__init__.py
http_root/index.tmpl
http_root/css/
http_root/css/main.css
http_root/ordner1/
http_root/ordner1/__init__.py
http_root/ordner1/index.tmpl
http_root/ordner2/
http_root/ordner2/__init__.py
http_root/ordner2/index.tmpl
lib/
lib/__init__.py
lib/constants.py
log/
templates/
templates/__init__.py
templates/mainnav/
templates/mainnav/__init__.py
templates/mainnav/template.tmpl
templates/pagetemplate/
templates/pagetemplate/__init__.py
templates/pagetemplate/template.tmpl
templates/pagetemplate/header.tmpl
templates/pagetemplate/footer.tmpl
Natürlich gibt es wieder mal mehrer Möglichkeiten um so ein Projekt umzusetzen. Ich wollte nur "eine" davon aufzeigen.
Das Beispiel als ZIP-Datei:
http://halvar.at/krimskrams3/cherrypy_c ... xample.zip
mfg
Gerold
