Seite 1 von 1
bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 12:48
von lackschuh
Hallo
Folgendes Problem:
Ich hab ein main.tpl, welches ein HTML Grundgerüst (inkl. meta Daten, Navigation etc) beinhaltet und ein paar content Templates wie home.tpl, kontakt.tpl. Im main.tpl habe ich ein jQuery ajax Aufruf im Header:
Code: Alles auswählen
$(document).ready(function() {
$("#pilight").change(function() {
var isChecked = $("#pilight").is(":checked") ? 1:0;
$.ajax({
url: '/control',
type: 'POST',
data: { strID:'pilight', strState:isChecked }
});
});
});
Das Handling mit den Tamplates habe ich bis jetzt immer so gelöst:
Code: Alles auswählen
from string import Template
@route("/home")
def index():
tpl = template('main')
t = Template(tpl)
home = template('home')
return t.substitute(content=home)
und mit dem $-Platzhalter mir im main.tpl immer den aktuellen Inhalt geladen (
$content). Leider beginnt die jQery Funktion auch mit $ und so stürzt das App ab. Wie könnte ich das umgehen?
Leider werde ich aus der Doku nicht schlau, was
hier gemeint ist...
mfg
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 12:55
von Sirius3
@lackschuh: damit solche Probleme erst gar nicht aufkommen, sollte Javascript-Code immer in einer separaten Datei abgelegt werden.
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 13:00
von BlackJack
@lackschuh: Was hat denn das jetzt mit `bottle` oder dessen Templates zu tun wenn Du ein Problem mit `string.Template` aus der Standardbibliothek hast? Da stellt sich mir als erste Frage warum verwendest Du zusätzlich zu `bottle`\s Templates auch noch `string.Template`? Das ist verwirrend und sehr wahrscheinlich unnötig.
@Sirius3: Irgendeinen Aufrufpunkt wird man aber fast immer im HTML haben, also zum Beispiel ``$(document).ready(external_function)``, und schon hat man ein ``$`` im Quelltext.
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 13:08
von lackschuh
Hallo
@BlackJack
Sry, das Problem wird von string.Template verursacht. Mir fällt aber sonst nichts ein, wie ich 'dynamisch' ins main.tpl Inhalt (aus home.tpl, kontakt.tpl) laden kann.
http://bottlepy.org/docs/dev/stpl.html#stpl.include
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 13:56
von Sirius3
@BlackJack: das '$(document).read' gibt es ja gerade deshalb, damit man kein Javascript im HTML (z.B. als 'onload' im <body>) braucht.
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 14:11
von BlackJack
@lackschuh: Dafür bieten die meisten Template-Bibliotheken Vererbung. Laut Dokumentation kann man das bei `bottle`\s Templates mit `rebase()` machen. Also müsstest Du in Deinem `main.tpl` ``$content`` durch ``{{base}}`` ersetzen und im `home.tpl` mit ``% rebase('main.tpl')`` anfangen.
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 14:18
von lackschuh
Hallo
1.
Aber den obgenannten jQuery Code einfach in eine .js Datei packen geht ja auch nicht. Wie löse ich dann die Funktion aus, wenn im Template steht:
Code: Alles auswählen
<label for="switch">Pi-Light</label>
<input type="checkbox" data-role="flipswitch" name="switch" id="pilight">
2. Wäre ich froh, wenn mir jemand die
Template Funktionen von bottle kurz erklären könnte. Aus dieser Doku werde ich leider nicht schlau bzw verstehe nicht, was da gemeint ist.
Edit:
Dank dir BlackJack.
Edit:
Wenn ich % rebase('main.tpl') in die erste Zeile von home.tpl einfüge, dann kommt folgender Fehler:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 862, in _handle
return route.call(**args)
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 1729, in wrapper
rv = callback(*a, **ka)
File "test.py", line 32, in index
home = template('index')
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 3592, in template
return TEMPLATES[tplid].render(kwargs)
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 3396, in render
self.execute(stdout, env)
File "/usr/local/lib/python2.7/dist-packages/bottle.py", line 3383, in execute
eval(self.co, env)
File "/home/pi/Python/Bottle/views/main.tpl", line 73, in <module>
{{base}}
NameError: name 'base' is not defined
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 15:25
von BlackJack
@lackschuh: Ad 1.: Du musst nur das JavaScript in eine eigene Datei verschieben und die im HTML dann einbinden.
Ad 2.: Im Text schreibst Du was von 'home.tpl' das per `rebase()` 'main.tpl' einbindet, im Traceback stolpert das Programm dann aber über ein Template das 'index' heisst. Wie denn nun?
Was soll man denn zu den Funktionen noch erklären? `rebase()` ist ziemlich einfach und macht genau das was in der Dokumentation beschrieben steht. Und ein Beispiel ist in der Dokumentation doch auch. Es wird das Template ausgewertet in dem das `rebase()` am Anfang steht, und dann wird das ausgewertete Template an den Namen `base` gebunden und das Template aus dem `rebase()`-Aufruf damit ausgewertet. Man kann dort also irgendwo ``{{base}}`` einsetzen.
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 18:26
von lackschuh
Ja das stimmt und danke für die Erklärung. Sry. Ich hab die Templates wie in der Doku umbenannt und aber in der App vergessen diese auch umzubenennen.
Leider geht es aber trotzdem nicht.
Code: Alles auswählen
@route("/stream")
def live_stream():
stream = template('stream.tpl')
return stream
Der Browser gibt folgendes aus: % rebase('base.tpl') also genau so, wie es im Template steht.
Das HTML Grundgerüst mit css etc. steht in der base.tpl. Dort habe ich an der Stelle, wo der Inhalt aus stream.tpl geladen werden soll {{base}} eingefügt.
Bottle v0.12.7 wird verwendet.
stream.tpl
Code: Alles auswählen
% rebase('base.tpl)
<form>
<label for="switch">Pi-Light</label>
<input type="checkbox" data-role="flipswitch" name="switch" id="pilight">
<br>
<input type="button" value="LINKS" id="left" />
<input type="button" value="RECHTS" id="rigth" />
<input type="button" value="HOCH" id="up" />
<input type="button" value="RUNTER" id="down" />
</form>
base.tpl
Code: Alles auswählen
<!DOCTYPE html>
<html>
<head>
<title>{{title or 'No title'}}</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/css/jquery.mobile.icons.min.css" />
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.3/jquery.mobile.structure-1.4.3.min.css" />
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="header"><h1>LIVE STREAM</h1></div>
<div data-role="navbar">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Page Two</a></li>
<li><a href="#">Search</a></li>
</ul>
</div>
<div data-role="main" class="ui-content">
{{base}}
</div>
</div>
</body>
</html>
Handle ich es in der App falsch?
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 18:43
von BlackJack
@lackschuh: In dem Template fehlt beim Dateinamen ein '.
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 19:03
von lackschuh
Ach so, das habe ich vergessen zu schreiben. Wenn ich hier eine falsche Syntax verwende wie zB % rebase asfsdf oder so ändert sich nichts. Also keine Fehlermeldung etc. auch mit der korrekten wie:
% rebase('base.tpl', title='Hallo Welt')
passiert nichts. Es wird exakt das ausgegeben, was im Template steht.
Komischerweise geht aber folgendes:
Code: Alles auswählen
% rebase('base.tpl', title='Hallo Welt')
<ul>
% for item in range(5):
<li>{{item}}</li>
% end
</ul>
Sieht im Quelltext so aus:
% rebase('base.tpl', title='Hallo Welt')
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
Das rebase geht bei mir nicht.
Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 19:19
von BlackJack
Bei mir funktionierts. Bottle 0.12.7. Gerade eben ausprobiert.

Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 19:47
von lackschuh
wie sieht bei dir die @route Methode aus?
mfg
Edit:
Hab bottle deinstalliert (pip uninstall bottle) und das bottle.py File ins Verzeichnis gelegt. Geht aber auch nicht

Re: bottle - SimpleTemplate Engine
Verfasst: Mittwoch 23. Juli 2014, 19:59
von BlackJack
@lackschuh: Keine `route()` ich habe einfach die Templates ausprobiert.
Re: bottle - SimpleTemplate Engine
Verfasst: Donnerstag 24. Juli 2014, 07:59
von lackschuh
Also folgendes geht:
Im base.tpl füge ich ''% include('stream.tpl')'' ein und gebe das Template mit
Code: Alles auswählen
@route("/stream")
def live_stream():
return template('base.tpl')
zurück.
Nur bringt mir das in meinem Fall nichts. Die 'rebase()' Methode mit {{base}} kapiere ich immer noch nicht bzw dessen richtige Anwendung.
base.tpl
- home.tpl
- stream.tpl
- control.tpl
Wie krieg ich es nun gebacken, dass das jeweilige 'content' Template im base.tpl eingefügt wird.
Code: Alles auswählen
@route("/stream")
def control():
return template('control.tpl')
Re: bottle - SimpleTemplate Engine
Verfasst: Montag 4. August 2014, 10:35
von lackschuh
Hallo
Ich hab nun mal alles gelöscht und neu installiert. Nun scheint es zu gehen aber irgendwie wird der pure HTML Code im Browser angezeigt.
Im Browser und Template zB:
<form method="post" action="/login"> <table> <tr><td>Username:</td><td><input type="text" name="username" size="20"></td></tr> <tr><td>Password:</td><td><input type="password" name="password" size="20"></td></tr> <tr><td><input type="submit" value="Log in"></td><td> </td></tr> </table> </form>
Im Quelltext des Browsers:
Code: Alles auswählen
<form method="post" action="/login">
<table>
<tr><td>Username:</td><td><input type="text" name="username" size="20"></td></tr>
<tr><td>Password:</td><td><input type="password" name="password" size="20"></td></tr>
<tr><td><input type="submit" value="Log in"></td><td> </td></tr>
</table>
</form>
Wenn ich anstelle von ''{{base}}'' ''%include'' einfüge, dann wird alles wunderbar angezeigt nur kommt dann in der Konsole die Warnung, dass 'include' und 'rebase' neu eine Funktion sei.
Re: bottle - SimpleTemplate Engine
Verfasst: Dienstag 5. August 2014, 09:41
von lackschuh
Wird hier ja langsam ein Monolog
Hier die Lösung
Anstelle von ''{{base}}'' -> ''{{!base}}
Quelle:
https://github.com/defnull/bottle/issues/624