jinja2 macros vs jsp2.0标签

时间:2011-10-12 20:07:14

标签: java python jsp jinja2

我是 java 程序员,学习 python / jinja

我对jinja2宏的最大优势是拥有一个调用者()的限制。 例如,我可以在jsp2标签中执行以下操作:

标签def:

<% 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>

我想要压力的是,正文内容和“标题”属性都包含动态的内容。此外,这里没有将变量设置为动态内容并将其传入的黑客攻击。

现在让我们看一下做同样事情的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 个答案:

答案 0 :(得分:5)

所以实际上这是Mako Templates for Python的核心功能。它没有广泛使用的功能,但它对我很重要,因为它在你提到的自定义模板标签中非常关键,所以它就在那里:

http://www.makotemplates.org/docs/defs.html#calling-a-def-with-embedded-content-and-or-other-defs

JSP是Mako从中汲取灵感的几个模板系统之一。

答案 1 :(得分:5)

除了dave建议的hack之外,您还可以将本地宏结果传递给任何其他宏。当您事先不知道将在本地定义传递参数或者它将来自模板变量时,这尤其有用:

{% 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() }}

答案 2 :(得分:3)

所以你是对的,你不能传递多个块。但是,您可以将变量传递回调用者,它可以对其进行操作。因此,您可以这样做:

{% macro test() %}
{{ caller('a') }}
{{ caller('b') }}
{% endmacro %}

{% call(which) test() %}
{% if which == 'a' %}hello
{% elif which == 'b' %}world
{% endif %}
{% endcall %}

为了更详细地描述,call(which)定义了一个带有一个参数which的调用者。当宏引用调用者时,它会向调用者传递一个实际上希望调用者返回的内容块的标识符。然后呼叫者可以采取行动。

这不是优雅或傻瓜证明,但它有效。

答案 3 :(得分:0)

现在有一个更好的解决方案:

http://mankyd.github.com/jinjatag/