Templating gesucht...

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Bisher habe ich in PyLucid ein sehr einfaches Templating mittels String-Operationen realisiert. Der Nachteil ist, das man quasi keine Schleifen (Tabelle mit wiederholenden Zeilen) einbauen kann :(

Nun suche nach einer Template Engine. Ich glaub SimpleTAL wäre eine schöne Sache, aber vielleicht gibt's da noch was anderes?

Es sollte folgende Eigenschaften erfüllen:
  • * einfacher Aufbau
    * möglichst kleines Modul
    * keine weiteren Modul Abhängigkeiten
    * sollte pures Python sein, da für CGI gebrauch
    * ab Python 2.2 lauffähig

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Ich kann dir nicht versprechen, dass das auf alle Anforderungen passt, aber für mich hört sich das arg nach Cheetah an.
http://www.cheetahtemplate.org/

Cheetah generiert aus deinen Templates Python-Files, ergo brauchst du die eigentliche cheetah-funktionalität zur laufzeit schon gar nicht mehr und musst nur die generierten files einbinden.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Danke für den Link... Für mich sieht das Beispiel so aus, als wenn man doch ein klein wenig Programm direkt in's Template hineinpflanzt... Das gefällt mir nicht so ganz.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Eigentlich nicht. Das heißt, jein. Wenn du for-schleifen etc.. willst, dann hat das Template natürlich programm-eigenschaften. Wie gesagt, es wird ja auch zu einem Python-Modul kompiliert.
Wenn du dann dieses Python-Mopul ausführst, erhälst du den End-Text. Mal ein kleines Beispiel:

foobar.tmpl:

Code: Alles auswählen

Hallo dies ist ein $irgendwas
An Cheetah mag ich, dass die Syntax nicht $what-ähnlich ist.
use_foobar.py:

Code: Alles auswählen

from foobar import foobar
foobar.irgendwas = "Cheetah-Template".
foobar.what = "HTML"
print str(foobar)
In der Shell macht man dann:

Code: Alles auswählen

> cheetah-compile foobar.tmpl
(...)
> python use_foobar
Hallo dies ist ein Cheetah-Template
An Cheetah mag ich, dass die Syntax nicht HTML-ähnlich ist.
PS:
Das Beispiel ist ein Fake, daher ungetestet, aber genau so funzt's.
Man hat aber auch 10000 andere Möglichkeiten, so kann man
das von cheetah generierte Python-File auch von hand ausführen und erhält (wenn cheetah ne chance hat, irgendwoher die Variablenbelegungen zu erfahren) auch das Ergebnis.

Ich bin ehrlich gesagt nicht sicher, ob ich wirklich verstanden habe, was dich an dem Konzept stört?!
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Danke für dein Beispiel. Ich hab auch noch welche gefunden: http://www.cheetahtemplate.org/docs/use ... d.tutorial

Ich muß über Vor-/Nachteile von Cheetah <-> simpleTAL nachdenken. Es ist vielleicht ganz gut, das Cheetah nicht wie simpleTAL "HTML"-like ist. Somit setzten sich die Template-Strings von den PyLucid-Tags ab...

Ist Cheetah auch pure Python, sodaß ich es auch als CGI ohne zusätze nutzten kann??

EDIT: Hab mir jetzt mal die Cheetah Doku etwas angesehen,,, Ich glaube es kann für meine Zwecke viel zu viel...
Ich brauche nur die grundlegendsten Templateeingenschaften. Bisher bin ich ja alleine mit String-Operatoren gut ausgekommen ;) Was halt noch fehlt sind wiederholbare Bereiche.
simpleTAL erscheint mir "kleiner" zu sein...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Laut meinem Paket-Manager besteht cheetah nur aus python-dateien.
(Abgesehen von der Dokumentation)

Btw: Ack, HTML-Tags in Templates sind hässlich, erst recht, wenn dabei sowas rauskommt:

Code: Alles auswählen

<table width="<get-table-width>" ...>
...
Ist natürlich für die armen syntax-highlightenden Editoren auch ne echte qual ,-)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also alleine an der Dateigrößen ist Cheetah um einiges Umfangreicher:
  • simpleTAL .\lib\simpletal\* - 94,9KB
    Cheetah \src\* - 262KB
Bei simpleTAL benötigt man nur eine Handvoll Dateien. Bei Cheetah ist es glaub ich wesendlich mehr...

Wobei das natürlich nicht viel über die Qualität oder die Eignung aussagt, aber ich möchte PyLucid nicht so super aufblähen ;)

EDIT: Hab nochmal im Forum gesucht:
http://www.python-forum.de/viewtopic.php?t=2203
Neben anderen Thread, wird eigentlich nur Cheetah empfohlen...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich hab mal im Wiki eine Seite zum Thema angelegt:
[wiki]Template Engines[/wiki]

EDIT: Einen etwas anderen Weg geht PyMeld.
Eigentlich ganz Witzig, aber ich weiß nicht, ob es in der Praxis nicht doch besser ist, das man klar sieht, wo was mit Platzhaltern aufgefüllt wird... Was meint ihr?
Zuletzt geändert von jens am Mittwoch 11. Januar 2006, 15:16, insgesamt 3-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Nun hab ich ein sehr interessantes Skript gefunden: Spytee

Ist nur eine 8KB kleine Datei und kann das was ich brauche.

Beispiele sind hier: http://www.pytan.com/code/spytee/examples.html

Ich glaube das ist genau das was ich gesucht hab!

EDIT: So nun hab ich mir mal den SourceCode näher angesehen.
So wie es aufgebaut ist, kann ich es leider nicht nutzten. Es erzeugt immer eine Python-Datei, die dann die eigentlichen Daten aufbaut.
Das ist zwar nett, weil es dadurch ein Caching gibt, aber für mich soll es ja mit PyLucid als CGI laufen. Da möchte ich keine neuen Dateien erzeugen.

Nun ist die Frage, ob es sowas wie spytee gibt, was nicht so arbeitet. Wenn nicht, werde ich wohl spytee einfach für mich umschreiben...

EDIT2: Hab mich etwas in den SourceCode eingearbeitet, aber ich denke nicht das es so einfach für mich anzupassen ist. Schade eigentlich.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, hab mit simpleTAL und Cheetah mal näher angesehen... Cheetah erscheint mir einfacher in der Benutzung als simpleTAL...

Allerdings ist die Preformance bei beiden nicht sooo doll:
simpleTAL import: 0.17sec. - ausführen: 0.01sec.
Cheetah import: 0.28sec - ausführen: 0.28sec.

(Nur ein sehr kleines Template/Daten Beispiel genommen, ich mach nochmal einen Test mit Loops)

Ist normalerweise kein Beinbruch, aber ich denke, wenn man sich auf Grundfunktionalität beschränkt, die ich nur brauche, dann geht's bestimmt auch schneller... Also doch wieder selbst programmieren? :(

EDIT: Cheetah mit einem Tabellenloop mit 100 Einträgen (Zeit ist ohne die erstellung der Daten!): 3.47sec.!!! Das ist echt nicht gerade schnell :( Mal sehen was simpleTAL dann macht...

EDIT2: So, simpleTAL ist da schon wesendlich schneller. Für die 100 Einträge braucht es nur 0.12sec. das ist im Vergleich zu Cheetah eine beachtliche Leistung!

Hier mal mein Code:

Code: Alles auswählen

        chapters = []
        for i in xrange(100):
            chapters.append(
                {"heading":"n%s" % i,
                "text":"fn%s" % i,
                "email":"j%s@eifh.com" % i}
            )
        #~ # A list that contains a dictionary
        #~ chapters = [{"heading": "Introduction", "text": "Some <b>text</b> here"}
                    #~ ,{"heading": "Details", "text": "Notice tags are preserved."}
                    #~ ]

        start_time = time.time()
        from simpletal import simpleTAL, simpleTALES
        print "import:", time.time()-start_time

        template = """<html>
          <body>
            <h1 tal:content="title">The title</h1>
            <table>
            <tr tal:repeat="chapters doc">
              <td tal:content="chapters/heading">Chapter Heading</td>
              <td tal:content="structure chapters/text">Text</td>
              <td tal:content="structure chapters/email">Text</td>
            </tr>
            </table>
        """

        start_time = time.time()
        # Create the context that is used by the template
        context = simpleTALES.Context()
        context.addGlobal("title", "Hello World")
        context.addGlobal("author", "Colin Stewart")

        advancedText = 'Structured text can contain other templates like this - written by <b tal:replace="author">Me</b>'

        chapters.append ({"heading": "Advanced", "text": simpleTAL.compileHTMLTemplate (advancedText)})
        context.addGlobal ("doc", chapters)

        template = simpleTAL.compileHTMLTemplate(template)

        template.expand(context, sys.stdout)

        print time.time()-start_time

Code: Alles auswählen

        daten = []
        for i in xrange(100):
            daten.append(
                {"surname":"n%s" % i,
                "firstname":"fn%s" % i,
                "email":"j%s@eifh.com" % i}
            )

        start_time = time.time()
        from Cheetah.Template import Template
        print "import:", time.time()-start_time

        template = """<h2>$title</h2>
        <p>$contents</p>
        <TABLE>
        #for $client in $service
        <TR>
        <TD>$client.surname, $client.firstname</TD>
        <TD><A HREF="mailto:$client.email" >$client.email</A></TD>
        </TR>
        #end for
        </TABLE>
        """
        nameSpace = {
            'title': 'Hello World Example', 'contents': 'Hello World!',
            "service": daten
        }

        start_time = time.time()
        print Template(template, searchList=[nameSpace])
        print time.time()-start_time

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Gleich vorweg: ich habe mir SimpleTAL angesehen udn da TAL aus Zope kommt habe ich wie immer bedenken. Das wäre etwas, was ich auch machen sollte, aber erstmal habe ich adere Prioritäten

Cheetah habe ich in Verbindung mit Spyce genutzt, das war recht lustig. Aber allzu viele leuchtende Features hatte es nicht. Es hat halt seine Aufgabe erfüllt.

In Verbindung mit TurboGears habe ich mir Kid angeschaut (anschauen müssen). Dazu hat Phillip J. Eby (Entwickler von PEAK, wo viele tolle Python-Codes herkommen) einen Blogeintrag geschrieben, wo er es mit seinem eigenen Templating System vergleucht. Was ich jetz sagen kann: Es ist im Gegensatz zu Cheetag ein reiner XML Generator (mit Cheetah kann man ja alles mögliche generieren), die Templates sind aber auch gültige XHTML-Dateien, die Kontrollinformationen im py-Namensraum haben. Dadurch kann man sich die Templates auch im Browser ansehen und mit beliebigen XML-Editoren komfortabel bearbeiten (oder man nutzt SciTE/vim wie ich). Beim ersten ausführen wird das Template in einen Python Bytecode kompiliert und ist von nun an schneller abrufbar. Das klingt etwas gewöhnungsbedürftig, aber wenn man etwas darüber nachdenkt könnte einem das Konzept sogar gefallen.

Nevow ist in etwa so ein Templating-System, wie Twisted ein simpler Netzwerkserver ist.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Leonidas hat geschrieben:Beim ersten ausführen wird das Template in einen Python Bytecode kompiliert und ist von nun an schneller abrufbar.
Das machen mittlerweile einige Template-Engines (s. pythonwiki.de/TemplateEngines) u.a. pyTemple und Spytee, die schön klein sind.

Das Problem ist nur, das ich es ja (natürlich) in PyLucid nutzten will und da ist es etwas schwierig, das Dateien abgelegt werden müßen. Es ist halt dieses nobody/nogroup Problem, mit den CGIs ausgeführt werden.
Natürlich könnte ich ein eigenes temp-Verzeichnis erzeugen mit chmod 777 aber schön ist das nicht.

Man könnte natürlich die Dateien auch in die SQL-DB "schreiben" lassen, aber ob das dann schon schnell/schneller ist, als jedesmal neu parsen??? Ich glaube ich hab immer relativ einfache Templates, weil es immer nur ein Teil der ganzen HTML-Seite ist.

z.Z. sehe ich mit simpleTAL näher an und versucht damit mal was zu machen. Wie ja tests ergeben haben, ist es recht flott...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Gast

Werden Template-Files denn zur Laufzeit verändert?
Ich versteh nicht, warum du die Template-files nicht einfach schon compilierst (also zu bytecode machst) bevor du das Template auf dem Server instalierst?

Das kann doch der Schreiber des Templates selbst machen, ist doch nichts aufwendiges (zuindest bei Cheetah), oder?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Na, wenn Kid die Templates kompiliert und sie nicht als Python Bytecode in pyc-Dateien speichert dann ist das ja auch kein Beinbruch, es funktioniert ja trotzdem.

Und vorkompilierte Dateien wären tatsächlich auch noch eine Lösung.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also es gibt in PyLucid die internal_pages, das sind dann Templates z.B. mit dem login-Formular oder mit der HTML-Form zum editieren von CMS-Seiten. Im Prinzip sollen alle Ausgaben von Modulen eine internal_pages benutzten. Diese internal_pages kann man online in einem normalen html-textarea bearbeiten.
Das klappt so eigentlich ganz gut.

Wenn ich jetzt sowas mache wie compilierte Templates, müßte ich also ein eigenes Cache-system schreiben. Das wäre IMHO nicht sehr aufwendig. Aber die Frage ist, ob sich das wirklich lohnen würde.

Interressant ist es aber schon...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
XT@ngel
User
Beiträge: 255
Registriert: Dienstag 6. August 2002, 14:36
Kontaktdaten:

hi Jens,
als Alternative kann ich noch
http://www.python-forum.de/viewtopic.php?t=2829 empfehlen.

Ein eigenes cache system zu schreiben lohnt sich auf jedenfall wenn eine Seite recht groß ist bzw wenn du viel traffic hast. bei PyLucid würd ich die Seiten schon nach dem erstellen oder editieren im cache ablegen.

ich würde in deinem fall,eine art cache ranking einführen. Also Seiten die nur Text und und keine dynamischen Elemente enthalten und die, wo spezielle Tags vorhanden sind z.B RSS Feed unterscheiden.
Im zweiten Fall würde ich bei jedem Besuch checken ob eine gewisse Zeit vergangen ist.


MfG
Andreas
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also eigentlich war PyLucid als kleines CMS für eine private Homepage gedacht.
Du bringst mich da aber auch eine Idee... Ich dachte immer nur an ein Caching für die internen Seiten. Nicht aber für die gesammte Seite!

Wobei es natürlich ein erheblicher Mehraufwand ist, der sich erst rechnet, wenn der Server mehr belastet ist...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich liebäugele immer noch mit SpyTee als Templat system, weil es einfach so super klein ist :) Auch wenn simpleTAL einen quasi-Standard (durch Zope) ist.

Dank XT@ngel Idee, könnte ich SpyTee so verwenden, das immer nach dem editieren eines Templates automatisch das compliliert wird und das wird in die DB geschrieben. Ist eigentlich total naheliegend :roll:

Ein Seiten-Cache kann/muss ja auch unabhängig von dem Template caching sein. Somit sind es eigentlich zwei verschiedene Sachen...

Ich werde mal versuchen das Template caching umzusetzten... Mal sehen 8)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, die Grundlagen sind vorhanden... Hab SpyTee verändert, so das man ein String als Template eingeben kann und als Kompilieren ByteCode zurück erhält:

http://www.jensdiemer.de/Programmieren/Python/SpyTee2


EDIT: Wie ich jetzt aber auch gesehen hab, existiert bei simpleTAL auch eine Art Chaching: TemplateCache
Mal sehen ob ich das nicht damit genau so machen kann, wie mit SpyTee2. Dann hätte ich die gesammte Funktionalität die TAL/TALES und Co. bieten...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also, ich denke ich werde simpleTAL nehmen. Spytee hab ich zwar nun auch umgebaut um es nutzten zu können, aber ich denke simpleTAL hat einfach ein paar Features mehr, die man evtl. später vermissen könnte.

Außerdem gibt es bei TAL mehr Hilfe/Doku aus der Zope-Ecke, was ja die Therads hier und hier schon bewiesen haben...

Sorry, wenn ich hier ein wenig rum genervt hab, aber so eine Umstellung sollte gut Überlegt sein :lol:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten