jinja2 宏与 jsp2.0 标签
我是一名Java程序员,正在学习Python/Jinja。
我对Jinja2宏最大的抱怨就是只能有一个调用者(caller())。举个例子,我可以在jsp2标签中这样做:
标签定义:
<% attribute name="title" fragment="true">
<div class='title'>${title}</div>
<div class='body'><jsp:doBody/></div>
使用示例:
<myTag>
<jsp:attribute name='title'>
<c:if test='${blah}'>This is only here sometimes</c:if>
</jsp:attribute>
<jsp:body>
<c:if test='${something}'>some dynamic content</c:if>
</jsp:body>
</myTag>
我想强调的是,内容和'title'属性都是动态的。而且这里没有什么技巧,比如设置变量来传递动态内容。
现在我们来看一个Jinja宏,它做的事情是一样的:
{% macro myTag(title='', caller) -%}
<div class='title'>{{ title }}</div>
<div class='body'>{{ caller() }}</div>
{%- endmacro %}
但是等一下!我不能轻易把动态内容放进'title'属性里!
{% call myTag(title='imagine putting some content here that involves 5 loops, 4 ifs and whatnot?') %}
{% if something %}some dynamic content{% endif %}
{% endcall %}
这是因为我还是个新手,还是Jinja的一个缺陷呢?
4 个回答
5
除了dave建议的技巧,你还可以把本地宏的结果传递给其他宏。这在你不知道传递的参数是本地定义的还是来自模板变量时特别有用。
{% macro doTag(title, body) %}
<div class='title'>{{ title }}</div>
<div class='body'>{{ body }}</div>
{% endmacro %}
{% macro tagBody() %}
{% if something %}some dynamic content{% endif %}
{% endmacro %}
{{ doTag(title='some simple title', body=tagBody() }}
{% macro tagTitle() %}
content here that involves 5 loops, 4 ifs
{% endmacro %}
{{ doTag(title=doTitle(), body=tagBody() }}
5
其实这是 Mako Templates for Python 的一个核心功能。虽然这个功能不是特别常用,但对我来说很重要,因为在你提到的自定义模板标签中,这个功能非常关键,所以它是存在的:
http://www.makotemplates.org/docs/defs.html#calling-a-def-with-embedded-content-and-or-other-defs
JSP 是 Mako 从中获得灵感的几个模板系统之一。
0
现在有了一个更好的解决方案: