Templating gesucht...

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Um das nochmal aufzuleben ^^
Ich hab jetzt das django template für nicht django nochmal umgesetzt, wenn auch mit einigen Verbesserungen und kleinerem Quellcode.

Nennt sich jinja und ist hier im Wiki eingetragen: Template Engines.

Und das ist absichtlich keine XML Template Engine, wird aber bald automatisch XHTML konformen Code erstellen können.
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:

Die Template Engine ist mit 36KB eine der Kleinsten, kennt allerdings Schleifen, If Conditions und besitzt ein Template Vererbungssystem mit dem man ein Basistemplate erweitern kann.
Also 36KB sind allerdings nicht wirklich klein... Spytee ist nur 12,8KB, kann aber keine Vererbung. SimpleTAL ist allerdings ca. 96KB groß...

Wo liegen denn genau die Unterschiede zwischen django und jinja???

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:

jens hat geschrieben:
Die Template Engine ist mit 36KB eine der Kleinsten, kennt allerdings Schleifen, If Conditions und besitzt ein Template Vererbungssystem mit dem man ein Basistemplate erweitern kann.
Also 36KB sind allerdings nicht wirklich klein... Spytee ist nur 12,8KB, kann aber keine Vererbung. SimpleTAL ist allerdings ca. 96KB groß...

Wo liegen denn genau die Unterschiede zwischen django und jinja???
Django ist ein ganzes Framework und die Template Engine ist nicht getrennt benuztbar. Jinja ist komplett alleinstehend, kennt Kommentare, Markers und hat eine bessere Filtersyntax. Filter dürfen auf Variablen zugreifen und Jinja kennt zusätzlich noch Integer, Boolen Werte (yes|true) und python None.
TUFKAB – the user formerly known as blackbird
henning
User
Beiträge: 274
Registriert: Dienstag 26. Juli 2005, 18:37

Ich fänds schön, wenn jemand die Zeit hätte, ein paar von den Infos hier (Größe der template-Engine, geschweindigkeit, Stärke der Trennung zwischen Coder und template, vererbungsfähigkeit, etc...) in das Wiki zu übertragen.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

henning hat geschrieben:Ich fänds schön, wenn jemand die Zeit hätte, ein paar von den Infos hier (Größe der template-Engine, geschweindigkeit, Stärke der Trennung zwischen Coder und template, vererbungsfähigkeit, etc...) in das Wiki zu übertragen.
Das wäre in der Tat was nettes. Vor allem, da ich atm noch keine Ahnung hab, wie sich Jinja schlägt.
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:

So, da haben wir doch den Benchmark:
simpleTAL:

Code: Alles auswählen

# -*- coding: utf-8 -*-

import sys, time
from SimpleTAL41 import simpleTAL, simpleTALES

t = """<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title tal:content="string:${title} | Testapplication"></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <div id="header" tal:content="string:${title} | Testapplication"></div>
    <ul id="nav">
        <li tal:repeat="data navigation">
            <a tal:attributes="href data/href;id string:btn-${'repeat/data/number'}" tal:content="data/caption" href="" id=""></a>
        </li>
    </ul>

    <table>
        <tr tal:repeat="row table" tal:attributes="class string:row${'repeat/row/number'}">
            <td tal:repeat="data row" tal:content="data"></td>
        </tr>
    </table>

</body>
</html>"""

context_dict = {
    'title': 'Some <test>',
    'navigation': [
        {'href': '#', 'caption': '<blub>'},
        {'href': '#', 'caption': 'asfasfasfd'},
        {'href': '#', 'caption': 'asfag asd asdg asdg'}
    ],
    'table': [
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0]
    ]
}


context = simpleTALES.Context()
context.globals.update(context_dict)

template = simpleTAL.compileHTMLTemplate(t)
template.expand(context, sys.stdout)

print
print "-"*80




class dummy:
    def write(self, _):
        pass

dummywriter = dummy()

print "alles zusammen start...",
start_time = time.time()
for i in xrange(200):
    context = simpleTALES.Context()
    context.globals.update(context_dict)

    template = simpleTAL.compileHTMLTemplate(t)
    template.expand(context, dummywriter)
end_time = time.time()

print "dauer: %0.3fsec" % (end_time-start_time)



print "ohne compile - start...",
template = simpleTAL.compileHTMLTemplate(t)
start_time = time.time()
for i in xrange(200):
    context = simpleTALES.Context()
    context.globals.update(context_dict)

    template.expand(context, dummywriter)
end_time = time.time()

print "dauer: %0.3fsec" % (end_time-start_time)



print "render only - start...",
context = simpleTALES.Context()
context.globals.update(context_dict)

template = simpleTAL.compileHTMLTemplate(t)
start_time = time.time()
for i in xrange(200):
    template.expand(context, dummywriter)
end_time = time.time()

print "dauer: %0.3fsec" % (end_time-start_time)
Ergebnis:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Some <test> | Testapplication</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div id="header">Some <test> | Testapplication</div>
<ul id="nav">
<li>
<a href="#" id="btn-1"><blub></a>
</li><li>
<a href="#" id="btn-2">asfasfasfd</a>
</li><li>
<a href="#" id="btn-3">asfag asd asdg asdg</a>
</li>
</ul>

<table>
<tr class="row1">
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td>
</tr><tr class="row2">
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td>
</tr><tr class="row3">
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td>
</tr><tr class="row4">
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td>
</tr><tr class="row5">
<td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>0</td>
</tr>
</table>

</body>
</html>
--------------------------------------------------------------------------------
alles zusammen start... dauer: 1.531sec
ohne compile - start... dauer: 0.860sec
render only - start... dauer: 0.859sec

jinja

Code: Alles auswählen

# -*- coding: utf-8 -*-

import time
from jinja import Template, Context, StringLoader

template = """<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{ title|escapexml }} | Testapplication</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

    <div id="header">{{ title|escapexml }} | Testapplication</div>
    <ul id="nav">
    {% for item in navigation %}
        <li><a href="{{ item.href }}" id="btn-{{ loop.counter }}">{{ item.caption|escapexml }}</a></li>
    {% endfor %}
    </ul>

    <table>
    {% for row in table %}
        <tr class="{% cycle 'row1', 'row2' inline %}">
        {% for col in row %}
            <td>{{ col|escapexml }}</td>
        {% endfor %}
        </tr>
    {% endfor %}
    </table>

</body>
</html>"""

context_dict = ({
    'title': 'Some <test>',
    'navigation': [
        {'href': '#', 'caption': '<blub>'},
        {'href': '#', 'caption': 'asfasfasfd'},
        {'href': '#', 'caption': 'asfag asd asdg asdg'}
    ],
    'table': [
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0],
        [1,2,3,4,5,6,7,8,9,0]
    ]
})

t = Template(template, StringLoader(), trim=True)
c = Context(context_dict)
print t.render(c)

print "-"*80


print "alles zusammen start...",
start_time = time.time()
for i in xrange(200):
    t = Template(template, StringLoader(), trim=True)
    c = Context(context_dict)
    t.render(c)
end_time = time.time()

print "dauer: %0.3fsec" % (end_time-start_time)



print "ohne compile - start...",
t = Template(template, StringLoader(), trim=True)
start_time = time.time()
for i in xrange(200):
    c = Context(context_dict)
    t.render(c)
end_time = time.time()

print "dauer: %0.3fsec" % (end_time-start_time)



print "render only - start...",
t = Template(template, StringLoader(), trim=True)
c = Context(context_dict)
start_time = time.time()
for i in xrange(200):
    t.render(c)
end_time = time.time()

print "dauer: %0.3fsec" % (end_time-start_time)
Ergebniss:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Some <test> | Testapplication</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>

<div id="header">Some <test> | Testapplication</div>
<ul id="nav">
<li><a href="#" id="btn-1"><blub></a></li>
<li><a href="#" id="btn-2">asfasfasfd</a></li>
<li><a href="#" id="btn-3">asfag asd asdg asdg</a></li>
</ul>

<table>
<tr class="row1">
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>0</td>
</tr>
<tr class="row2">
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>0</td>
</tr>
<tr class="row1">
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>0</td>
</tr>
<tr class="row2">
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>0</td>
</tr>
<tr class="row1">
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>0</td>
</tr>
</table>

</body>
</html>

--------------------------------------------------------------------------------
alles zusammen start... dauer: 1.953sec
ohne compile - start... dauer: 0.453sec
render only - start... dauer: 0.454sec
Nochmal die simpleTAL Werte zum besseren vergleich:
alles zusammen start... dauer: 1.531sec
ohne compile - start... dauer: 0.860sec
render only - start... dauer: 0.859sec

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:

http://wsgiarea.pocoo.org/trac/browser/ ... /tests/cmp

Hier ist ein Vergleichstest von Jinja, Kid, SimpleTAL und Cheetah. Es werden 5000 Renderings mit reimport gemacht, Caching ist überall aktiviert (SimpleTAL nicht, das hat kein Caching)

Durchschnittliche Renderzeit:

Code: Alles auswählen

blackbird@volverine:~/Developement/area51/tpltest$ python tpltest.py
Running Test 'jinja'
TIME 0.00307821240425
Running Test 'kid'
TIME 0.00703014059067
Running Test 'simpletal'
TIME 0.0100415547848
Running Test 'cheetah'
TIME 0.00251657156944
Cheetah Template wurde mit cheetah-compile vorkompiliert.
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:

Auch wen jinia etwas langsamer ist... Ich find es irgendwie dennoch nicht schlecht, weil es doch wesendlich einfach zu verstehen ist, als simpleTAL...

Weil simpleTAL doch etwas komplex ist, hab ich in PyLucid auch nur ein Module darin umgesetzt... Ich scheue irgendwie den Aufwand, sich in die Technik von simpleTAL reinzusteigern.
Was ich jetzt noch nicht beurteilen kann, ob simpleTAL oder jinja generell besser sind. Allerdings sind die Filterfunktionen von jinja schon ganz nett, das kann IMHO simpleTAL nicht...

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