2017-10-12 19 views
1

%的神社文檔的Assignments section,根據「作用域行爲」小節:補償用於分配的非持久性內Jinja2的循環

Please keep in mind that it is not possible to set variables inside a block and have them show up outside of it. This also applies to loops. The only exception to that rule are if statements which do not introduce a scope.

我理解else聲明中for循環能力,還有像loop.index這樣的特殊變量,但這些都不能解決我的問題。

我有一個小部件,它輸出的文章,但只有當它們符合一定的標準。爲了減少測試用例,這裏有一個簡單的例子代碼:

{% set maxiterations = 3 %} 
{% set iterations = 0 %} 
{% for item in seq %} 
    {% if item == "bar" and iterations < maxiterations %} 
    {{ item.foo }} 
    {% set iterations = iterations + 1 %} 
    {% endif %} 
{% endfor %} 

這當然是行不通的:迭代將總是等於1loop.index不會幫助;我不想計算被跳過的迭代。我該如何解決這個問題?

回答

1

雖然@SumanKalyan是絕對正確的(當它被設置在循環外不能修改循環內迭代) ,我發現他的解決方案,也沒有在Jinja2中可用的陳述似乎在我的上下文中被理解。

試圖@ SumanKalyan的建議或do像往常一樣返回的錯誤:

CRITICAL: TemplateSyntaxError: Encountered unknown tag 'iterations'. 
Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. 
The innermost block that needs to be closed is 'if'. 

缺少對do支持竟然是因爲缺乏這個擴展在我的具體應用(Pelican)的。我可以簡單地指定它,但我選擇了不同的路線。我發現了一個不同的答案,很大程度上得益於以下認識:Jinja2 for循環支持條件語句。因此:

{% set max_iterations = 3 %} 
{% for item in seq if item == "bar" %} 
    {% if index.loop < max_iterations %} 
     {{ item.foo }} 
    {% endif %} 
{% endfor %} 

這滿足的情況下的核心部分:僅輸出item.foo如果item == bar;不要使它成爲迭代的子集seq的一部分。

在我的實際實現中(超出這裏提供的測試用例),我有多個條件。一個需要根據外部設置變量的真實性和特定的循環迭代(第一個,正好發生)跳過項目。如何這樣的一個例子就解決了:

{% set baz == true %} 
{% if baz %} 
    {% set max_iterations = 4 %} 
{% else %} 
    {% set max_iterations = 3 %} 
{% endif %} 

{% for item in seq if item == "bar" %} 
    {% if index.loop < max_iterations and not(baz and loop.index == 1) %} 
     {{ item.foo }} 
    {% endif %} 
{% endfor %} 

對於好奇,實際的代碼(這也是viewable in context):

{# Only show the widget content if: 
    - There a configured count of articles to display 
    - There's any articles in articles_list 
    - There's at least 2 articles... 
    - ...Or at least 1 article if the widget count is set to 1 #} 

{% if ARTICLES_WIDGET_COUNT and articles_list|length != 0 and (articles_list|length > 1 or ARTICLES_WIDGET_COUNT == 1) %} 
    <aside class="siteFooter_articles widget"> 
     {% if ARTICLES_WIDGET_NAME %} 
      <h1 class="widget_title">{{ ARTICLES_WIDGET_NAME }}</h1> 
     {% endif %} 

     <ol class="imageList list-noType"> 
      {# If this is the index page, the first article is always displayed. 
      It gets skipped inside the loop, so increment the counter #} 
      {% if isindex %} 
       {% set max_iterations = ARTICLES_WIDGET_COUNT + 1 %} 
      {% else %} 
       {% set max_iterations = ARTICLES_WIDGET_COUNT %} 
      {% endif %} 

      {# Skip displaying this article if this is the page for the article being displayed in full 
      If this isn't an article page, always display the item (note the additional condition below for index pages) #} 
      {% for article in articles_list if article.url != thisarticle.url or thisarticle == null %} 
       {# If this is the index page and the first loop iteration, the article to be displayed in the widget would be the same one 
       displayed in full on the page. So, skip it. (Note the counter is incremented before the loop to account for this.) #} 

       {% if not(loop.index == 1 and isindex) %} 
        {% set articles_widget = true %} 
        {% include 'includes/articleitem.html' %} 
       {% endif %} 

       {# If the set number of articles have been added to the widget, we're done here. #} 
       {% if loop.index == max_iterations %} {% break %} {% endif %} 
      {% endfor %} 
     </ol> 

     <p class="readMore"> 
      <a class="readMore_link" href="{{ SITEURL }}/{{ ARTICLES_URL }}">More...</a> 
     </p> 
    </aside> 
{% endif %} 
1

如果您在循環外設置「迭代」,則無法在循環內對其進行修改。 您可以通過使用對象,而不是「重複」標破壞這種行爲:

{% set maxiterations = 3 %} 
{% set iterations = [0] %} 
{% for item in seq %} 
    {% if item == "bar" and iterations[0] < maxiterations %} 
    {{ item.foo }} 
    {% iterations.append(iterations.pop() + 1) %} 
    {% endif %} 
{% endfor %} 
+0

當嘗試這種解決方案,我得到:'CRITICAL:TemplateSyntaxError:遇到未知標記「迭代」。 Jinja正在尋找以下標籤:'elif'或'else'或'endif'。需要關閉的最裏面的塊是'if'。' – Tohuw

+0

我在'do'語句之前嘗試過,但收到相同的錯誤,但是這次未知標籤是'do'。這可能是[Pelican](http://getpelican.com)的限制嗎? – Tohuw

+0

發現爲什麼這不起作用,至少用'做'...看到我下面的答案。 – Tohuw