2011-10-12 38 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中的函數)因此,就像使用函數一樣,不需要爲了多次使用而重複宏定義。 –