我有一个列表,“foos”,如果我有超过5个“foos”,我想做一些特定于前2个的东西,然后是其他特定的东西。
所以我想在HTML中想要这样的东西:
<div id="accordion">
<p>Foo1<p>
<p>Foo2<p>
<div id="collapseMe" class="panel-collapse collapse">
<p>Foo3<p>
<p>Foo4<p>
etc...
</div>
</div>
<a data-parent="#accordion" href="#collapseMe"><p>Expand</p></a>
所以,我在Jinga2中解决了这个问题,但解决方案非常难看。我想知道我是否遗失了什么?
<div id="accordion">
{% for f in foos %}
{% if loop.index <= 2 %}
<p>{{ f.txt }}</p>
{% else %}
{% if loop.index == 3 %}
<div id="collapseMe" class="panel-collapse collapse">
<p>{{ f.txt }}</p>
{% else %}
<p>{{ f.txt }}</p>
{% endif %}
{% endif %}
{% endfor %}
{% if foos | length > 2 %}
</div>
<a data-parent="#accordion" href="#collapseMe"><p>Expand</p></a>
{% endif %}
</div>
虽然这有效但我认为必须有更好的方法来做到这一点。不幸的是,据我所知,Jinga2中的切片功能非常有限,也许还有另外一种方法可以解决这个问题吗?我还不完全清楚批处理功能如何工作,但这可能有用吗?
答案 0 :(得分:1)
您可以构建或查找过滤器,以便在for循环之前预先对foos
列表进行预分片。
{% for f in foos|slice:"0:10:2" %}
您可以将大部分模板循环逻辑移动到过滤器本身,或者使用简单路径并在列表中使用现有切片表示法:
from jinja2 import Environment, Undefined
def slice(iterable, pattern):
if iterable is None or isinstance(iterable, Undefined):
return iterable
# convert to list so we can slice
items = list(iterable)
start = None
end = None
stride = None
# split pattern into slice components
if pattern:
tokens = pattern.split(':')
if len(tokens) >= 1:
start = tokens[0]
if len(tokens) >= 2:
end = tokens[1]
if len(tokens) >= 3:
stride = tokens[2];
return items[start:end:stride]
在其他地方,将过滤器添加到Jinja2环境中。
env = Environment()
env.filters['slice'] = slice
请注意,这是有效的,因为[:::]
和[None:None:None]
是相同的切片表示法。