2012-12-24 18 views
7

Geçiş yaptığım adlar listesi var, her biri işleme gereksinimleri açısından biraz farklı, dolayısıyla bir özniteliğe göre uygun makroyu aramak istiyorum.jinja2: Makro makro veya dinamik makro çağrıları seçiliyor

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

ama ne istediğim gibi bir şey şudur:: Ben

getattr(object_with_method_to_produce_templates, item) 

ama sığınak gibi bir şey yapacağını düzenli Python bu noktada

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

Ne var bu attr filtresini etkili bir şekilde kullanmanın bir yolunu buldum (eğer bu durumda doğru şekilde kullanabiliyorsam).

Flask.get_template_attribute, ilginç olabilecek başka bir yere bakıyordum (eğer bunun yerine sadece önceden yapabilir ve şablona önceden hesaplanmış ve önceden biçimlendirilmiş bir öğe gönderebilir). Belki de şu anda yapmak istediğim şeyin çok ötesinde.

Gelecekte oldukça büyük olabilecek bir liste yerine makroların farklı bir listesinden arama yapmanın daha iyi bir yolu nedir? Ortak bir soru gibi görünüyor, ama aradığım tam cevapta tökezlemedim.

DÜZENLEME:

Ben madde nesil ben

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 %}') 

işlemek istediğiniz öğenin bir parçası olarak bir çağrılabilir makro ... oluşturmak için çalışıyor, ne yaptığımı bu katma ...

template = get_template_attribute(test_template, 'test_macro') 

... şablonunda ... her öğe

{{ item.template("testing this method") }} 
daha sonra öğeleri yineleme

Bu tür bir çalışma, yalnızca normal bir makro olarak değil, yalnızca harf için dize harfi üretir (ör. div'ler, yalnızca metin olarak, div olarak oluşturulmazlar).

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

Yani Template bazı bağlamda vermek gerekir, ya da bir şey bunun için amaçlayan ama doğru görünmüyor ne yakındır.

EDIT2: arıyordu, bu nedenle bu fena olanı

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

döner, ben vardı namedtuple düzenlemesi atlayıp sadece ... devamını Üzerinde çalışıyorum bir makro geçmek mümkün olabilir varsayalım. Bu optimal/tercih edilebilir mi yoksa karışık mıdır?

+0

Jinja belgelerinde ve güvenli filtrede HTML kaçışına bakın. – voscausa

+0

Tamam, baktım ama yapmam gereken tam bağlantıyı yapmadım.Yaptığımı düşündüğüm şey bir kod bloğu olarak bir makro oluşturmak, ancak html olarak işaretlemez (bir dosya uzantısı belirtilir), bu nedenle makro sadece düz metin olarak renksizleşir, hmmm bunun için biraz şaka yapalım. . – blueblank

cevap

5

Makroyu geçerli içerikten alan ve ardından Makro'yu değerlendiren bir Jinja2 filtresi oluşturabilirsiniz. filtresidir:

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

tam cevap here bakınız.