jinja2中的延迟渲染
Posted
技术标签:
【中文标题】jinja2中的延迟渲染【英文标题】:Delay rendering in jinja2 【发布时间】: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 中执行此操作。
【参考方案1】:
只需使用内置loop
变量的first
和last
属性:
% for item in menu_items %
<li class="
%- if loop.first %first% endif -%
%- if loop.last %last% endif -%">
# The remainder of your conditions and rendering go here #
</li>
% endfor %
【讨论】:
我曾考虑过类似的事情,不幸的是,第一个/最后一个函数知道菜单项是第一个还是最后一个。可能是菜单列表中的最后一项根本没有呈现,迫使 n-1 项成为最后一个可见项。 @Richard - 好吧,我不得不承认现在被难住了 -menu_items
是一个列表还是完全是其他某种数据结构?
它本身并不是一个真正的数据结构。正如我原来的帖子所示,它们是在模板中定义的。
@Richard - 所以,为了确保我理解你的正确 - 模板中定义了所有菜单项 - 但根据局部变量的状态,某些元素可能会被隐藏(@987654327 @)?
是的,没错。我开始认为 jinja 无法实现我想要做的事情,话虽如此,我有一个解决方法的想法:- 为列表中的第一个和最后一个预创建两个 。 以上是关于jinja2中的延迟渲染的主要内容,如果未能解决你的问题,请参考以下文章