【发布时间】:2011-12-02 12:39:27
【问题描述】:
我最近从 django 模板转换为 jinja2,到目前为止,我在移植现有模板时没有遇到太多麻烦,但现在我的任务是转换我们的自定义 django 模板标签。我遇到的问题是一个标签,用于创建类似菜单的结构,它看起来像:
{% createmenu mainmenu %}
<!-- syntax: menuitem url-name-to-resolve <url-args> <url-kwargs> "Url Label" -->
{% menuitem main-url-name 'Home' %}
{% menuitem some-other-url-name obj.foo obj.bar 'Page2' %}
{% if some_condition %}
{% menuitem some-other-url-name obj.foo obj.bar 'Page2' %}
{% endif %}
{% menutemplate %}
<li class="
{% if menu.is_selected %}selected{% endif %}
{% if menu.is_first %}first{% endif %}
{% if menu.is_last %}last{% endif %}">
{% if menu.is_active %}
<a href="{{menu.url}}">{{menu.label}}</a>
{% else %}
<span class="inactive">{{menu.label}}</span>
{% endif %}
</li>
{% endcreatemenu %}
这种行为使得在菜单项上设置类变得更加简单,例如,菜单在渲染时知道它是列表中的第一个还是最后一个,所以如果我在 if 条件下包围一个菜单项,它可能更改它或其他节点是第一个显示还是最后一个显示。
现在到神社。我已经尝试过上下文函数、扩展和宏,但我似乎无法获得相同的行为,因为我不知道如何延迟菜单项的呈现,直到我知道要呈现哪些菜单项。目前我完全不知道如何继续,任何帮助将不胜感激。
【问题讨论】:
-
Jinja 模板调用 Python 函数出了什么问题?什么没用?你遇到了什么问题?
-
感谢您的回复,并为我的延误感到抱歉。问题是 jinja 在处理它们时会渲染所有节点。所以 AST 看起来像:
MENU[ MENUITEM, MENUITEM, IF[ MENUITEM]]当它被渲染时,我怎么知道第三个或第二个菜单项是最后一个被渲染的?在我的 django 版本中,我做了一些 hacky;我渲染它(不显示)并计算渲染了多少菜单项,然后我再次调用 render 现在知道哪个项目是最后一个。我不确定如何在 jinja 中执行此操作。