jinja2: macro seleccionando macro o llamadas dinámicas de macro

Tengo una lista de las variables nombradas por las que estoy pasando, cada una de ellas ligeramente diferente en cuanto a los requisitos de representación, por lo que quiero llamar a la macro adecuada en función de un atributo. Lo que tengo es esto:

{% macro format_item(item) %} {% if item.type_of == 'a' %} {{ format_a(item) }} {% elif item.type_of == 'b' %} {{ format_b(item) }} {% elif item.type_of == 'c'%} {{ format_c(item) }} {% elif item.type_of == 'd'%} {{ format_d(item) }} {% else %} {{ format_general(item) }} {% endif %} {% endmacro %} 

pero lo que quiero es algo como:

 ...iterating through list of items {{ call macro based off item.type_of }} 

en este punto en Python regular me gustaría hacer algo como

 getattr(object_with_method_to_produce_templates, item) 

pero no he encontrado una manera de usar el filtro attr de manera efectiva (si puedo usarlo adecuadamente en esta situación).

He encontrado flask.get_template_attribute buscando en otro lugar, lo que podría ser interesante (si puedo, por el contrario, hacerlo todo antes de tiempo y enviar un elemento precalculado y preformateado a la plantilla). Tal vez demasiado y más allá de lo que quiero hacer en este momento.

¿Cuál es una mejor manera de llamar desde una lista variada de macros en lugar de una lista de si entonces eso podría ser bastante grande en el futuro? Parece una pregunta común, pero no he encontrado la respuesta exacta que estoy buscando.

EDITAR:

Agregué esto a lo que estaba haciendo, tratando de generar una macro invocable como parte del elemento que quiero procesar.

 from flask import get_template_attribute from jinja2 import Template test_template = Template('{% macro test_macro(item) %}
sent to me: {{ item }}
{% endmacro %}')

… en la generación de elementos …

  template = get_template_attribute(test_template, 'test_macro') 

… en la plantilla … iterar elementos luego para cada elemento

 {{ item.template("testing this method") }} 

qué tipo de trabajo funciona, pero solo genera la cadena letra por letra, no como lo haría una macro normal (es decir, los divs no se representan como divs, solo como texto).

 
sent to me: testing this method

Así que necesito darle a Template algo de contexto, o algo más cercano a lo que buscaba pero no parece correcto.

EDIT2:

 {{ item.template("testing this method")|safe }} 

devuelve lo que estaba buscando, así que esto es pasable, podría ser capaz de omitir el arreglo de doble nombre que tenía y simplemente pasar una macro con … más trabajando en eso, supongo. ¿Es esto óptimo / preferible o un desastre sin embargo?

Puede crear un filtro Jinja2 que obtenga la Macro del contexto actual y luego evalúe la Macro. El filtro es:

 @contextfilter def call_macro_by_name(context, macro_name, *args, **kwargs): return context.vars[macro_name](*args, **kwargs) 

Vea la respuesta completa aquí .