Seite 1 von 2
Jinja 1
Verfasst: Donnerstag 1. März 2007, 08:18
von mitsuhiko
Gut. Zuerst warum das Ding in "Ideen" steht und nicht im Showcase. Weil ich noch ein paar Ideen suche
Also zuerst: was ist Jinja 1? Django Templates - NodeList + Compilierung - "Krüppelsyntax". Also zumindest mal Django Templates nur mit erweiterter (fast Python Syntax) und Quellcode Generierung für mehr Performance. Allerdings nach wie vor sandboxed (Template Desigern können den Anwendungsquellcode nicht kaputt machen oder sonst irgendetwas tun, dass die Sicherheit gefährden würde).
Und jetzt ein paar Fragen die vor allem an Leute gerichtet sind, die schon was mit der Django Template Engine gemacht haben:
1.) Nutzt ihr {{ block.super }}? Ich würde dieses Feature in Jinja gerne fallen lassen, da man dafür die überschrieben Blöcke mitführen müsste und dies den generierten Quellcode aufbläst.
2.) Welche Features fehlen euch an der Django Template Engine?
Jinja 1 sieht momentan so aus:
Code: Alles auswählen
<h1>Reversed Userlist mit Foobar</h1>
{% for user in users|reverse %}
{% if loop.even or user.active or user.user_id is even %}
foobar mit {{ user|escape }}
{% elif loop.odd and user.username == "buzz" %}
blah
{% else %}
hehe
{% endif %}
{% endfor %}
In Django wäre der Großteil von dem da oben nicht möglich. Zugegeben ist das Beispiel da auch absolut sinnlos, aber es zeigt was Jinja 1 momentan ist.
Momentane Features und Unterschiede zu django:
* austauschbare Blocksyntax ({% zu <% oder ähnliches)
* Python Kompatible Syntax (list comprehensions und ein paar ähnliche Dinge wurde nicht implementiert) aber andere Semantiken: Nur unicode Strings, is Operator führt Tests aus ({% if something is even %} / {% if something is lower %} etc.), else Block in For-Schleifen wird ausgeführt, wenn nicht iteriert wurde.
* Der Translator erzeugt gültigen Python Code aus den Templates, damit schneller als Django Templates. Wenn auch der Unterschied nicht so groß ist.
* Macros (wie Python Funktionen)
* For-Schleifen können rekursiv verwendet werden.
* Filter erlauben mehrere Argumente ({{ foo|replace("blub", "blah")|escape }})
Also wer noch gute Ideen hat oder meine Fragen von oben beantworten kann hat gute Chancen, dass die Änderungen noch in das 1.0 Release kommen
Verfasst: Donnerstag 1. März 2007, 09:39
von jens
Da du schon geschrieben hast, das for-Schleifen rekursiv verwendet werden können, habe ich eigentlich keine Fragen mehr
Jedoch würde ich überlegen, braucht man wirklich alle Sachen? Ich meine verführt das nicht ehr dazu, mehr Logik vom Programm aus in das Template zu verlagern, als es wirklich nötig ist???
Was genau sollte man z.B. mit Macros machen?
Du bastelst doch irgendwie gleichzeitig mit JS rum. Was soll das erledigen können? Soll am Ende nur die Daten an JS weitergegeben werden und JS baut dann die Seite zusammen?
Verfasst: Donnerstag 1. März 2007, 12:40
von mitsuhiko
Also ja, es läd ein mehr Logik in die Templates zu packen. Aber du kannst zb keine Python Code Blöcke verwenden oder sowas. Makros helfen einfach nur häufig benutzte Dinge zusammenzufassen. Beispielsweise, wenn du Dialogboxen hast die mehr als nur ein DIV sind.
Die Logik von den Templates verhalten kannst und musst du immer noch. Keine einzige Python Funktion ist im Namespace, abgesehen von xrange das als Ersatz für {% range %} herhalten muss.
Der JavaScript Übersetzer macht, wenn er fertig ist aus Jinja templates einfach JavaScript Funktionen, denen du dann ein object übergeben kannst um nach HTML zu rendern. Sehr praktisch für AJAX Anwendungen, du sparst dir das am Server rendern.
Verfasst: Donnerstag 1. März 2007, 13:00
von jens
Ach, noch was.
Django hat ja dieses newforms Zeug:
http://www.djangoproject.com/documentation/newforms/
Vielleicht macht es ja Sinn das irgendwie zu verknüpfen. Frag mich bitte aber nicht wie
Mir ist nur eingefallen das man mit diesen newforms auch html Formulare bauen kann. Was u.a. die Aufgabe für ein Template ist.
Verfasst: Donnerstag 1. März 2007, 15:46
von rafael
Ich fände es cool, wenn die Operatoren "<", ">" usw. verfügbar wären.
Damit kann man beispielweise testen ob ein Text so und so lang ist und den gegebenenfalls splitten/kürzen.
Verfasst: Donnerstag 1. März 2007, 15:49
von jens
@rafael: IMHO gehört das ins Programm und nicht in das Template!
Verfasst: Donnerstag 1. März 2007, 16:22
von rafael
jens hat geschrieben:@rafael: IMHO gehört das ins Programm und nicht in das Template!
Wäre aber einfacher, wenn sowas in dem Template verfügbar wäre. Man kann ja auch das Datum vorher formatieren, aber es gibt nen Datumsfilter
Wenn man beispielsweise mit ner DB oder so arbeitet, kann man das dann fix, wie das Datum im Template bearbeiten.
Verfasst: Donnerstag 1. März 2007, 16:25
von dst
Nein, ich denke rafael hat da schon recht. Wenn das Template erfordert, dass bestimmte Inhalte auf bestimmte Weise dargestellt werden, dann gehört das ins Template und nicht in die Logik.
Verfasst: Donnerstag 1. März 2007, 16:33
von BlackJack
@jens: Da lässt sich drüber streiten. Wenn die Trennung Template/Programm die von Darstellung/Logik sein soll, dann gehört "überlangen Text umbrechen" IMHO zur Darstellung, hätte also durchaus seine Berechtigung im Template.
Verfasst: Donnerstag 1. März 2007, 16:55
von mitsuhiko
@rafael: das geht bereits.
@jedie: Sowas gehört ins Template. Wenn es die Darstellung beeinflusst ist das sicher nichts für den Controller, sondern den View. (in Terms of MVC)
Verfasst: Donnerstag 1. März 2007, 17:05
von apollo13
Ich persönlich finde block.super recht nützlich und verwende es auch gern!
Verfasst: Donnerstag 1. März 2007, 19:48
von veers
Was mir an der django template engine klar fehlt:
Ein include wo ich einen Context übergeben kann. Fehlt aber auch in cheetah und anderen template engines. Werde mir sowas wohl mal basteln
Verfasst: Donnerstag 1. März 2007, 20:16
von mitsuhiko
veers hat geschrieben:Was mir an der django template engine klar fehlt:
Ein include wo ich einen Context übergeben kann. Fehlt aber auch in cheetah und anderen template engines. Werde mir sowas wohl mal basteln
Wie meinst du das?
Verfasst: Donnerstag 1. März 2007, 20:36
von veers
blackbird hat geschrieben:veers hat geschrieben:Was mir an der django template engine klar fehlt:
Ein include wo ich einen Context übergeben kann. Fehlt aber auch in cheetah und anderen template engines. Werde mir sowas wohl mal basteln
Wie meinst du das?
Ich versuchs mal am Beispiel eines Shops zu erklären:
Eine View für eine Produkt Liste:
Code: Alles auswählen
return render_to_response("productlist.html", ["newestproduct": newestproduct, "products": allproducts])
productlist.html:
Code: Alles auswählen
<h1>Neustes Produkt</h1>
{{ include "product.html", ["product": newestproduct] }}
<h1>Alle Produkte</h1>
{{ for product in products }}
{{ include "product.html", ["product": product] }}
{{ endfor }}
product.html:
Code: Alles auswählen
<strong>{{ product.name }}</strong> - {{ product.price }}
Dürfte derzeit schon auf dem einen oder anderen weg möglich sein, jedoch habe ich keinen schönen weg gefunden ({{ for product in [newestproduct] }}...).
Edit (Leonidas): Code in Tags gesetzt.
Edit (mitsuhiko): Code Tags korrigiert
Verfasst: Donnerstag 1. März 2007, 21:06
von mitsuhiko
In Jinja 1 geht das auch nicht. Steht auch nicht auf der Liste der Dinge die ich jetzt direkt einbauen werde weil da ein wenig Magie dabei ist. Wenn der Wunsch wirklich sehr groß ist lässt sich über sowas aber reden.
Ich werfe nur mal eben Macros ein die genau eine solche Situation vermeiden sollten:
productlist.html:
Code: Alles auswählen
{% include 'product_helper.html' %}
<h1>Neustes Produkt</h1>
{{ show_product(newestproduct) }}
<h1>Alle Produkte</h1>
{% for product in products %}
{{ show_product(product) }}
{% endfor %}
product_helper.html:
Code: Alles auswählen
{% macro show_product product %}
<strong>{{ product.name }}</strong> - {{ product.price }}
{% endmacro %}
Verfasst: Donnerstag 1. März 2007, 21:22
von veers
Hm, irgend wie gefallen mir diese Makros einfach nicht wirklich. Da ich sie aber in diesem Zusammenhang nie verwendet habe mags auch nur am Namen liegen
Django kennt ja noch "Inclusion Tags" siehe
http://www.djangoproject.com/documentat ... es_python/. Etwas umständlicher als ich es gerne hätte aber vermutlich besser weil expliziter..
Verfasst: Freitag 2. März 2007, 08:19
von jens
blackbird hat geschrieben:Ich werfe nur mal eben Macros ein die genau eine solche Situation vermeiden sollten:
productlist.html:
Code: Alles auswählen
{% include 'product_helper.html' %}
<h1>Neustes Produkt</h1>
{{ show_product(newestproduct) }}
<h1>Alle Produkte</h1>
{% for product in products %}
{{ show_product(product) }}
{% endfor %}
product_helper.html:
Code: Alles auswählen
{% macro show_product product %}
<strong>{{ product.name }}</strong> - {{ product.price }}
{% endmacro %}
Hm. lässt sich das nicht über die normale block-includes lösen?
Verfasst: Freitag 2. März 2007, 17:11
von veers
Ich wüsste nicht wie... Kannst du mal ein Beispiel machen?
Verfasst: Montag 5. März 2007, 10:00
von jens
Hm. Dann ist block und macro also dahingehend Unterschiedlich: Macro kann man eine Variable übergeben, block allerdings nicht.
Verfasst: Dienstag 6. März 2007, 13:05
von mitsuhiko
So. Jinja 1 ist jetzt glaub ich in Feature Freeze. Jetzt werden nur noch Fehler gesucht und behoben. So schaut jetzt die Syntax und Designerdokumentation aus:
http://pocoo.org/~mitsuhiko/jinjadocs/designerdoc.html
Wer Fehler findet oder noch Verbesserungen hat, her damit