Comment dois-je appeler defs modèle avec des noms connus seulement à l'exécution dans le langage de template Python Mako?
Question
Je suis en train de trouver un moyen d'appeler des modèles def déterminés par les données disponibles dans le contexte.
Modifier Une instance plus simple de la même question.
Il est possible d'émettre la valeur d'un objet dans le contexte:
# in python
ctx = Context(buffer, website='stackoverflow.com')
# in mako
<%def name="body()">
I visit ${website} all the time.
</%def>
Produit:
I visit stackoverflow.com all the time.
Je voudrais permettre une personnalisation de la sortie, sur la base des données.
# 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>
Modification de l'attribut format
dans le contexte devrait changer la sortie de
I visit stackoverflow.com all the time.
à
I visit <a href='http://stackoverflow.com'>stackoverflow.com</a> all the time.
composée syntaxe J'ai utilisé dans le body
de def
est évidemment faux. Qu'aurais-je besoin de préciser de manière dynamique un modèle, puis l'appeler?
La solution
prend un certain jeu avec l'espace de noms local
de Mako, mais voici un exemple de travail:
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()
Si on le souhaite, ce émet:
I visit
<a href='http://stackoverflow.com'>stackoverflow.com</a>
all the time.
Autres conseils
Que diriez-vous si vous devez d'abord générer le modèle (à partir d'un autre modèle :), puis exécutez que vos données?