Jinja 1

Du hast eine Idee für ein Projekt?
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Gut. Zuerst warum das Ding in "Ideen" steht und nicht im Showcase. Weil ich noch ein paar Ideen suche :D

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 :D
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
rafael
User
Beiträge: 189
Registriert: Mittwoch 26. Juli 2006, 16:13

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.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

@rafael: IMHO gehört das ins Programm und nicht in das Template!

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
rafael
User
Beiträge: 189
Registriert: Mittwoch 26. Juli 2006, 16:13

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.
dst
User
Beiträge: 27
Registriert: Mittwoch 28. Februar 2007, 23:42

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.
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.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

@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)
TUFKAB – the user formerly known as blackbird
apollo13
User
Beiträge: 827
Registriert: Samstag 5. Februar 2005, 17:53

Ich persönlich finde block.super recht nützlich und verwende es auch gern!
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

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 ;)
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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?
TUFKAB – the user formerly known as blackbird
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

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
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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 %}
TUFKAB – the user formerly known as blackbird
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

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..
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Ich wüsste nicht wie... Kannst du mal ein Beispiel machen?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hm. Dann ist block und macro also dahingehend Unterschiedlich: Macro kann man eine Variable übergeben, block allerdings nicht.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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 :D
TUFKAB – the user formerly known as blackbird
Gesperrt