_рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЬрд╣рд╛рдВ рдореБрдЭреЗ рдкрд╣рд▓реА рдмрд╛рд░ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛ рд╡рд╣ рдЕрдзрд┐рдХ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ-рдИрд╢ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдЕрдзрд┐рдХ рд╕рд╣рдЬ рддрд░реАрдХреЗ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реВрдВред_
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИ:
{%- macro _tag(tag, id=none, classes=(), attrs={}) -%}
<{{ tag }}
{% if id %} id="{{ id }}" {% endif %}
{% if classes %} class="{{ classes|join(' ') }}" {% endif %}
{{ attrs|xmlattr }}>
{% if caller %} {{ caller() }} {% endif %}
</{{ tag }}>
{%- endmacro -%}
рдПрдХ рдЙрдЪреНрдЪ рд╕реНрддрд░реАрдп рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдЬреЛ рдЗрд╕реЗ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП {% call %}
рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИ:
{%- macro _div() -%}
{% call _tag('div', *varargs, **kwargs) %}
{% autoescape false %}
{% if caller %} {{ caller() }} {% endif %}
{% endautoescape %}
{% endcall %}
{%- endmacro -%}
рд╕рд╣рдЬ рд░реВрдк рд╕реЗ, {% call _div(...) %} <b>foo</b> {% endcall %}
рдХрд░рдиреЗ рд╕реЗ <b>foo</b>
рдХреЛ _tag
рдореИрдХреНрд░реЛ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рддрдм рдЗрд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдЧрд╛ (рд╢рдмреНрджрд╢рдГ, рдСрдЯреЛрд╕реНрдХреЗрдк рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж)ред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдгрд╛рдо UndefinedError: No caller defined
{{ caller() }}
рд▓рд╛рдЗрди рдкрд░ _div
рдХреЗ рдЕрдВрджрд░ рд╣реИред рдРрд╕рд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ caller
рдХрд╛ рджрд╛рдпрд░рд╛ {% call %}
рдмреНрд▓реЙрдХ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдКрдкрд░ рджрд░реНрд╢рд╛рдП рдЧрдП рдЬреИрд╕реЗ рдЬрдВрдЬреАрд░ рдХреЙрд▓ рдХреЛ рд░реЛрдХрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдПрдХ рдмрджрд╕реВрд░рдд рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ 2.8 рд╕реЗ рдирдИ рдмреНрд▓реЙрдХ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ:
{%- macro _div() -%}
{% set content %}
{% if caller %} {{ caller() }} {% endif %}
{% endset %}
{% call _tag('div', *varargs, **kwargs) %}
{% autoescape false %} {{ content }} {% endautoescape %}
{% endcall %}
{%- endmacro -%}
рд▓реЗрдХрд┐рди, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдЕрдзрд┐рдХ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ред
рдореИрдВ рдЗрд╕реЗ рдЗрд╕ рдЫреЛрдЯреЗ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдкреБрди: рдкреЗрд╢ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реВрдВ:
{% macro a() %}
start of a
{% call b() %}
{{ caller() }}
{% endcall %}
end of a
{% endmacro %}
{% macro b() %}
start of b
{{ caller() }}
end of b
{% endmacro %}
{% call b() %}
inside b only
{% endcall %}
{#
{% call a() %}
inside a
{% endcall %}
#}
рдпрд╣ рдареАрдХ рд╡реИрд╕реЗ рд╣реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЬрдм рдЕрдВрддрд┐рдо рдмреНрд▓реЙрдХ рдЕрд╕рдореНрдмрджреНрдз рд╣реЛрддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЯреНрд░реЗрд╕рдмреИрдХ рдорд┐рд▓рддрд╛ рд╣реИ:
Traceback (most recent call last):
...
File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "templates/test.j2", line 19, in top-level template code
{% call a() %}
File "templates/test.j2", line 3, in template
{% call b() %}
File "templates/test.j2", line 11, in template
{{ caller() }}
File "templates/test.j2", line 4, in template
{{ caller() }}
jinja2.exceptions.UndefinedError: No caller defined
рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЫреЛрдЯрд╛ рдиреЛрдЯ:
2.8 рдХреА рдирдИ рд╕реБрд╡рд┐рдзрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рднреА рдареАрдХ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИ:
{% macro a() %}
start of a
{% set content=caller() %}
{% call b() %}
{{ content }}
{% endcall %}
end of a
{% endmacro %}
{% macro b() %}
start of b
{{ caller() }}
end of b
{% endmacro %}
{% call b() %}
inside b only
{% endcall %}
{% call a() %}
inside a
{% endcall %}
рдпрд╣ рдЬрд╛рдирдмреВрдЭрдХрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╣рдореЗрд╢рд╛ рдирд┐рдХрдЯрддрдо рдореИрдХреНрд░реЛ рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИред рд╡реЛрдВрдЯрдлрд┐рдХреНрд╕ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдВрдж рдХрд░рдирд╛ред
рдПрдлрд╡рд╛рдИрдЖрдИ, {% set caller_ = caller %}
рднреА рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдЬрдм рднреА рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рдЗрд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╡реИрд╕реЗ рднреА, рдпрд╣ рдЕрдХреНрд╕рд░ рдкреВрдЫреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд╛рдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдореБрдЭреЗ рдпрд╛рдж рд╣реИ рдХрд┐ рдХреБрдЫ рд╕рдордп рдкрд╣рд▓реЗ рдПрдХ рд╕рд╣рдХрд░реНрдореА рдХреЛ рднреА рдпрд╣реА рд╕рдорд╕реНрдпрд╛ рдереА рдЬрдм рддрдХ рдХрд┐ рд╣рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рдЪрд▓рд╛ рдХрд┐ {% set caller_ = caller %}
рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЙрд▓ рдмреНрд▓реЙрдХ рдореЗрдВ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдорджрдж рдХрд░рддрд╛ рд╣реИред
рд╣рд╛рдБ, рд╣рдо рдЗрд╕реЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЫреЛрдЯрд╛ рдиреЛрдЯ:
2.8 рдХреА рдирдИ рд╕реБрд╡рд┐рдзрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рднреА рдареАрдХ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИ: