2010-07-01 59 views
1

我在Jinja2中有一個自定義標記,我只想在第一次調用時輸出一些東西。所以說,我有以下的模板:如何確保Jinja自定義標籤只輸出一次?

1. {% only_once %} 
2. {% only_once %} 
3. {% only_once %} 

我所要的輸出是:

1. "I only get printed once!" 
2. 
3. 

我猜做到這一點的最好的辦法是設置一個標誌,在模板的上下文跟蹤我是否已經打印了某些東西。這是一個代碼示例,但是這是正確的嗎?

class OnlyOnceExtension(Extension): 
    tags = set(['only_once']) 

    @contextfunction 
    def parse(self, context, parser): 
     if hasattr(context, 'my_flag') and context.my_flag: 
      return Output("") 
     else: 
      return Output("I only get printed once!") 

這是正確的嗎?我讀了一些關於上下文的東西是不可變的,所以這不起作用? (見http://jinja.pocoo.org/2/documentation/api和搜索不可變)

回答

4

我的建議是實現這個在Python代碼:

class OnlyOnce(object): 
    def __init__(self, data): 
     self.data = data 
     self.printed = False 

    def __str__(self): 
     if self.printed is False: 
      self.printed = True 
      return self.data 
     return '' 

在Python代碼創建一個OnlyOnce實例,並把它傳遞給模板,然後每次你想使用它,只需使用{{ only_once }}

我注意到很多人使用Jinja的一件事情是,他們想用Django-ish的方式做事,即編寫擴展。但Jinja的表達式/導入/任何功能都足夠強大,您不必爲所有內容使用擴展。

是的,使用context.my_flag的東西是一個壞主意。只有模板才能修改上下文。 永遠。

1

我會定義一個布爾值和宏,然後從那裏開始。不是打印變量,而是打印使用if語句和布爾值的宏的結果以決定是否應該打印。所以,你會得到如下:

{{ set was_printed = false }} 
{% macro print_once(to_print) %} 
    {% if was_printed is sameas false %} 
     {{ to_print }} 
     {% set was_printed = true %} 
    {% endif %} 
{% endmacro %} 
1. {% print_once(only_once) %} 
2. {% print_once(only_once) %} 
3. {% print_once(only_once) %} 
+1

我試圖用這個宏,但它不是有效的代碼,'TemplateSyntaxError:預計令牌'打印聲明結束',得到'was_printed' ' – topless 2012-12-19 11:18:13

3

如果你想與神社這樣做純粹是你可以檢查在時尚loop.index變量,

{% for bar in bars %} 
    {% if loop.index == 1 %} 
     Print me once 
    {% endif %} 
    Print me every time 
{% endfor %} 
相關問題