UI-Module in der Tornado Template-Engine

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Tornados Django-ähnliche Template-Sprache hat eine IMHO interessante kleine Erweiterung, auf die ich mal hinweisen wollte. Man kann UI-Module, die wenn man mich fragt, ja besser UI-Komponenten geheißen hätten, damit man sie nicht mit Python-Modulen verwechselt, schreiben, mit denen man wiederverwendbare Komponenten realisieren kann, die ihr eigenes CSS oder JavaScript mitbringen.

Hier ist ein Beispiel:

Code: Alles auswählen

# uimodules.py
class Teaser(tornado.web.UIModule):
    def css_files():
        return ["teaser.js"]

    def render(self, article):
        return self.render_string("teaser_%s.html" % article.kind, article=article)

# index.html
{% for article in featured_articles %}
  {{ modules.Teaser(article) }}
{% end %}
Die Klasse `Teaser` muss registriert werden, dann kann man sie in Templates über `modules` ansprechen und beliebige Dinge tun, die letztlich einen String erzeugen, der an der passenden Stelle eingefügt werden. Im einfachsten Fall kann man z.B. ein spezielles Template einbinden. Wird so ein Modul benutzt, werden automatisch einmal die deklarierten CSS- oder JavaScript-Dateien zur Seite hinzugefügt.

Mir gefällt die Idee. Für "echte" Komponenten wäre es jedoch nett, wenn man den Rumpf einer Komponente wieder im Template definieren könnte, etwa wenn man etwas haben will, das einen Rahmen oder eine Box generisch darstellen soll.

Djangos Inclusion Tags sind ähnlich, aber aufwendiger zu definieren und sie können nicht der Seite CSS oder JavaScript hinzufügen. Djangos Form Widgets können letzteres, sind aber nicht mit Templates gestaltbar.

Defnull, bitte sowas auch in Bottle einbauen :)

Stefan
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Ich kann mir durchaus einen Templatetag vorstellen, der in Django genau das gleiche tut, bzw eine Kombination aus zweien, da ich gerne die css Files nach unten packe:

Code: Alles auswählen

<html>
<body>
...
  {% include module.Teaser %}
...
{% include_media %}
</body>
</html>
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Naja, aber das zerstört ja die schöne Trennung von Model, View und Controller, oder Model, View und Template, wenn man so will. Denn wenn man es ganz genau nimmt, dann hat Python-Code nichts im Template zu suchen; und außerdem hat man dann Logik im View. Das ist Müll.

Im Übrigen sollte für solche Fälle doch das normale Include-Tag ausreichend sein.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Tornado Module können, müssen aber nicht neben Darstellung auch Logik enthalten. Eine strickte Trennung wird manchmal auf überbewertet. Wer ist z.B. für das Ermitteln einer Bestenliste verantwortlich? Logik oder Darstellung? Ich würde ja sagen, Darstellung, denn es geht darum, vorhandene Dinge einfach anders darzustellen. Der Übergang ist natürlich fließend, abhängig davon, was "bester" zu sein bedeutet.

Normale Include-Tags reichen nicht, weil sie keine (gebundenen) Variablen haben. Es sind Makros. Und das ist zu wenig, weil sie dadurch call-by-name Semantik haben und nicht call-by-value. Außerdem müsste ich, um zum Header JS-Dateien, zum style CSS-Regeln und zum Body JS-Code hinzufügen zu können, 4 zusammengehörige Dateien includen, was total fehleranfällig wäre.

Stefan
Antworten