Como faço para chamar defs modelo com nomes conhecidos apenas em tempo de execução no modelo de linguagem Python Mako?

StackOverflow https://stackoverflow.com/questions/923837

  •  06-09-2019
  •  | 
  •  

Pergunta

Eu estou tentando encontrar uma maneira de chamar def moldes determinados pelos dados disponíveis no contexto.

Editar: Um exemplo simples da mesma pergunta.

É possível emitir o valor de um objeto no contexto:

# in python
ctx = Context(buffer, website='stackoverflow.com')

# in mako
<%def name="body()">
I visit ${website} all the time.
</%def>

Produz:

I visit stackoverflow.com all the time. 

Eu gostaria de permitir uma personalização da saída, com base nos dados.

# 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>

A alteração do atributo format no contexto deve mudar a saída do

I visit stackoverflow.com all the time.

para

I visit <a href='http://stackoverflow.com'>stackoverflow.com</a> all the time.

O composta sintaxe Eu tenho usado no body def está obviamente errado. O que eu preciso especificar dinamicamente um modelo e, em seguida, chamá-lo?

Foi útil?

Solução

Toma algum jogo com namespace local de mako, mas aqui está um exemplo de trabalho:

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()

Como desejado, Emite:

I visit 
<a href='http://stackoverflow.com'>stackoverflow.com</a>
 all the time.

Outras dicas

E se você primeiro gerar o modelo (de outro modelo :), e depois executar isso com seus dados?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top