2012-12-24 4 views
7

나는 각각의 렌더링 요구 사항이 약간 다른 namedtuples 목록을 가지고 있으므로 속성을 기반으로 적절한 매크로를 호출하고 싶습니다.jinja2 : 매크로 또는 동적 매크로 호출 매크로

{% 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 %} 

하지만 내가 원하는 것은 같은 것을하는 것입니다 : 내가

getattr(object_with_method_to_produce_templates, item) 

하지만 천국 같은 것을 할 거라고 일반 파이썬이 시점에서

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

을 내가해야하는 것은 이것이다 attr 필터를 효과적으로 사용할 수있는 방법을 찾지 못했습니다 (이 상황에서 제대로 사용할 수 있다면).

flask.get_template_attribute가 흥미로울 수있는 곳을 찾고 있습니다. 대신에 모든 것을 미리 수행하고 미리 계산되고 미리 서식이 지정된 항목을 템플릿에 보내면됩니다. 어쩌면 지금 너무 많이하고 싶다.

미래에 다소 커질 수있는 목록이 아닌 다양한 종류의 매크로 목록에서 전화하는 더 좋은 방법은 무엇입니까? 일반적인 질문처럼 보이지만, 나는 정확한 대답을 찾지 못했습니다.

편집 :

내가 항목 생성에 내가

from flask import get_template_attribute 
from jinja2 import Template 
test_template = Template('{% macro test_macro(item) %}<div id="test-div">sent to me: {{ item }}</div>{% endmacro %}') 

을 렌더링 할 항목의 일부로 호출 매크로를 ... 생성하기 위해 노력하고, 내가 무엇을하고 있었는지이 추가 ...

template = get_template_attribute(test_template, 'test_macro') 

... 템플릿 ... 각 항목

{{ item.template("testing this method") }} 
에 대한 다음 항목을 반복

어떤 종류의 작동하지만 편지 용 문자열 문자 만 생성합니다. 일반 매크로가 아닙니다. div는 div로 렌더링되지 않고 텍스트로만 렌더링됩니다).

<div id="test-div">sent to me: testing this method</div> 

그래서 템플릿에 약간의 컨텍스트를 제공해야합니다. 즉, 목표에 더 가깝지만 옳지 않은 것으로 보입니다.

EDIT2 : 내가 찾고, 그래서이 무난 무엇

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

반환, 나는 내가 가진 namedtuple 배열을 무시하고 단지로 ... 더 나는 그것을 작업 매크로를 통과 할 수있을 것 가정 해. 이 최적의/바람직한 또는 엉망이야?

+0

Jinja 문서 및 안전 필터에서 HTML 이스 케이 핑을 확인하십시오. – voscausa

+0

좋아, 나는 그들을 살펴 봤지만 내가해야 할 정확한 연결을하지 못했다.내가 한 일은 코드 블록으로 매크로를 만드는 것인데, 파일 확장자가 가리키는 것처럼 html로 표시하지 않기 때문에 매크로는 일반 텍스트로 다시 변환된다. . – blueblank

답변

5

현재 컨텍스트에서 매크로를 가져 와서 매크로를 평가하는 Jinja2 필터를 만들 수 있습니다. 필터는 다음과 같습니다

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

전체 응답 here를 참조하십시오.