为什么 pelican/jinja2 不再设置变量?

Why does pelican/jinja2 not set the variable again?

我有以下脚本:

<div class="blog-archives">
    {% set last_year = 0 %}
    {% for article in dates %}
        {% set year = article.date.strftime('%Y') %}
        {% if last_year != year %}
            <h2 id="{{year }}" title="last_year={{last_year}}"><a href="#{{year}}">{{ year }}</a></h2>
            {% set last_year = year %}
        {% endif %}
        {% set next_year = 0 %}
        {% if not loop.last %}
            {% set next = loop.index0 + 1 %}
            {% set next_article = dates[next] %}
            {% set next_year = next_article.date.strftime('%Y') %}
        {% endif %}
        {% if next_year != year %}
            <article class="last-entry-of-year">
        {% else %}
            <article>
        {% endif %}
        <a href="{{ SITEURL }}/{{ article.url }}">{{ article.title }} {%if article.subtitle %} <small> {{ article.subtitle }} </small> {% endif %} </a>
        <time pubdate="pubdate" datetime="{{ article.date.isoformat() }}">{{ article.locale_date }}</time>
        </article>
    {% endfor %}
</div>

我认为会导致这样的结果:

但实际上我得到了

问题是 {% set last_year = year %} 似乎没有被执行 - last_year 的值始终为 0。有人知道为什么以及如何解决它吗?

与 Python 不同,在 Jinja2 中,for 循环有自己的命名空间;因此,您在循环内设置的变量是循环的局部变量,一旦在循环外,同名变量将恢复为外部范围之一。

您可以使用 namespace 对象来解决这个问题:

{% set ns = namespace(last_year=0) %}
{% for article in dates %}
    {% set year = article.date.strftime('%Y') %}
    {% if ns.last_year != year %}
        <h2 id="{{year }}" title="last_year={{ns.last_year}}"><a href="#{{year}}">{{ year }}</a></h2>
        {% set ns.last_year = year %}

详情请参阅namespace的文档。