макросы jinja2 против тегов jsp2.0 - PullRequest
4 голосов
/ 13 октября 2011

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

что я хочу подчеркнуть , так это то, что и содержимое тела, и атрибут '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 %}

это проблема с тем, что я новичок, или это недостаток дзиндзя?

Ответы [ 4 ]

5 голосов
/ 13 октября 2011

Так что на самом деле это основная особенность Шаблоны Mako для Python . Эта функция не так широко используется, но она важна для меня, так как она довольно важна для пользовательских тегов шаблонов, как вы упомянули, поэтому она есть:

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

JSP - это одна из нескольких систем шаблонов, от которых Мако черпает вдохновение.

5 голосов
/ 13 октября 2011

В дополнение к хаку, предложенному Дейвом, вы можете передать результат локального макроса любому другому макросу.Это особенно полезно, если вы заранее не знаете, будет ли передан параметр, определенный локально, или он будет получен из переменной шаблона:

{% 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() }}
3 голосов
/ 13 октября 2011

Так что вы правы в том, что не можете пропустить несколько блоков. Тем не менее, вы можете передать переменную обратно вызывающей стороне, на которую она может воздействовать. Поэтому вы можете сделать что-то вроде этого:

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

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

Чтобы описать это более подробно, call(which) определяет вызывающую сторону, которая принимает один аргумент, which. Когда макрос ссылается на вызывающего, он передает вызывающему идентификатор идентификатора блока контента, который он на самом деле хочет, чтобы вызывающий возвращал. Затем вызывающий абонент может действовать в соответствии с этим.

Это не элегантно и не глупо, но работает.

0 голосов
/ 30 декабря 2011

и теперь есть лучшее решение:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...