2011-10-12 39 views
4

我是java程序员学习python/jinjajinja2宏vs jsp2.0标签

我最大的牛肉与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> 

我想压力这里,是,无论是身体内容和“标题”属性的内容为动态。同时,有没有黑客在这里变量设置为动态内容并通过他们的

现在让我们来看看一个神社宏,做同样的事情:

{% macro myTag(title='', caller) -%} 
    <div class='title'>{{ title }}</div> 
    <div class='body'>{{ caller() }}</div> 
{%- endmacro %} 

但等待! 我不容易把动态内容放入标题属性!

{% call myTag(title='imagine putting some content here that involves 5 loops, 4 ifs and whatnot?') %} 
    {% if something %}some dynamic content{% endif %} 
{% endcall %} 

这是我作为一个新手的问​​题,还是这是一个忍者的缺点?

回答

3

所以你是对的,你不能通过多个块。但是,您可以将变量传回给调用者,它可以采取行动。因此,你可以做这样的事情:

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

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

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

这不是优雅或者无所事事,但它的工作原理。

5

除了戴夫建议的黑客,你可以将本地宏结果传递给任何其他宏。这是非常有用的,当你事先不知道将要传递的参数本地定义,否则将来自模板变量:

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

这是一个合理的解决方案 - 比我建议的更具弹性。我把它称为合理的,并不好,因为它比较冗长和沉重。此外,如果您想多次调用父宏,则必须多次定义这些一次性宏。 –

+0

@dave:你可以传递宏本身而不是调用的结果('{{doTag(body = tag_Body)}}'并且在需要的时候用参数调用它。把宏看作函数(实际上它是jinja2中的函数)因此,就像使用函数一样,不需要为了多次使用而重复宏定义。 –