简体   繁体   English

jinja2 macros vs jsp2.0标签

[英]jinja2 macros vs jsp2.0 tags

I am a java programmer learning python/jinja . 我是一个学习python / jinjajava程序员。

My biggest beef with jinja2 macros is the limitation of having a single caller(). 使用jinja2宏的最大优点是拥有一个调用者()的限制。 for example, i could do the following in jsp2 tags: 例如,我可以在jsp2标签中执行以下操作:

tag def: 标签def:

<% attribute name="title" fragment="true">
<div class='title'>${title}</div>
<div class='body'><jsp:doBody/></div>

usage: 用法:

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

what i want to stress here, is that both the body content and the 'title' attribute have content that is dynamic . 我想强调的是,正文内容和“标题”属性都具有动态内容。 also, there are no hacks here of setting variables to dynamic content and passing them in. 此外,这里没有将变量设置为动态内容并将其传入的黑客攻击。

now lets look at a jinja macro that does the same thing: 现在让我们看一下做同样事情的jinja宏:

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

but wait! 可是等等! i cannot easily put dynamic content into the title attribute! 我不能轻易地将动态内容放入title属性!

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

is this a problem with my being a newbie, or is this a shortcoming of jinja? 这是我新手的问题,还是这是jinja的缺点?

So in fact this is a core feature of Mako Templates for Python . 所以实际上这是Mako Templates for Python的核心功能。 It's not as widely used of a feature but it's important to me, as it's pretty critical in custom template tags as you mention, so it's there: 它不是广泛使用的功能,但它对我很重要,因为它在你提到的自定义模板标签中非常关键,所以它在那里:

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

JSP is one of several template systems Mako draws inspiration from. JSP是Mako从中汲取灵感的几个模板系统之一。

In addition to hack suggested by dave you can pass local macro result to any other macro. 除了dave建议的hack之外,您还可以将本地宏结果传递给任何其他宏。 This is especially useful when you don't know in advance will be passed parameter defined locally or it will come from template variable: 当您事先不知道将在本地定义传递参数或者它将来自模板变量时,这尤其有用:

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

So you're right in that you can't pass multiple blocks. 所以你是对的,你不能传递多个块。 However, you can pass a variable back to the caller, which it can act upon. 但是,您可以将变量传递回调用者,它可以对其进行操作。 Therefore, you can do something like this: 因此,您可以这样做:

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

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

To describe that in more detail, call(which) defines a caller that takes one argument, which . 为了描述在更详细地, call(which)定义了一个呼叫者它有一个参数, which When the macro refers to the caller, it passes to the caller an identifier for the block of content it actually wants the caller to return. 当宏引用调用者时,它会向调用者传递一个实际上希望调用者返回的内容块的标识符。 The caller can then act upon this. 然后呼叫者可以对此采取行动。

It's not elegant or fool proof, but it works. 这不是优雅或傻瓜证明,但它的工作原理。

and now there is a better solution: 现在有一个更好的解决方案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM