Wie kann ich Vorlagen defs mit Namen rufen nur zur Laufzeit in der Template-Sprache Python bekannt Mako?
Frage
Ich versuche, einen Weg zu finden, der durch die Daten im Kontext bestimmt def Vorlagen aufrufen.
Edit: Eine einfachere Instanz derselben Frage.
Es ist möglich, den Wert eines Objekts im Kontext zu emittieren:
# in python
ctx = Context(buffer, website='stackoverflow.com')
# in mako
<%def name="body()">
I visit ${website} all the time.
</%def>
Erzeugt:
I visit stackoverflow.com all the time.
Ich möchte eine Anpassung der Ausgabe ermöglichen, auf der Grundlage der Daten.
# in python
ctx = Context(buffer, website='stackoverflow.com', format='text')
# in mako
<%def name="body()">
I visit ${(format + '_link')(website)} all the time. <-- Made up syntax.
</%def>
<%def name='html_link(w)'>
<a href='http://${w}'>${w}</a>
</%def>
<%def name='text_link(w)'>
${w}
</%def>
Ändern das format
Attribut im Kontext sollte die Ausgabe von
I visit stackoverflow.com all the time.
I visit <a href='http://stackoverflow.com'>stackoverflow.com</a> all the time.
Die aus Syntax Ich habe in dem body
def
verwendet wird, ist offensichtlich falsch. Was würde ich dynamisch eine Vorlage angeben müssen, und dann nennen?
Lösung
nimmt einiges Spiel mit Makos local
Namespace, aber hier ist ein funktionierendes Beispiel:
from mako.template import Template
from mako.runtime import Context
from StringIO import StringIO
mytemplate = Template("""
<%def name='html_link(w)'>
<a href='http://${w}'>${w}</a>
</%def>
<%def name='text_link(w)'>
${w}
</%def>
<%def name="body()">
I visit ${getattr(local, format + '_link')(website)} all the time.
</%def>
""")
buf = StringIO()
ctx = Context(buf, website='stackoverflow.com', format='html')
mytemplate.render_context(ctx)
print buf.getvalue()
Wie gewünscht, diese emittiert:
I visit
<a href='http://stackoverflow.com'>stackoverflow.com</a>
all the time.
Andere Tipps
Wie wäre es, wenn Sie zuerst die Vorlage generieren (aus einer anderen Vorlage :), und führen Sie das mit Ihren Daten?