假设我有这个带有宏的模板(这些是简化的):
{# macros.html #}
{% macro a(opts = {}) %}
{{ opts.a }}
{% endmacro %}
{% macro b(opts = {}) %}
{{ opts.b }}
{% endmacro %}
Run Code Online (Sandbox Code Playgroud)
而这一个包含覆盖
{# macros_override.html #}
{% macro a(opts = {}) %}
Overridden: {{ opts.a }}
{% endmacro %}
Run Code Online (Sandbox Code Playgroud)
然后我希望在同一名称空间下有一个包含所有这些宏的模板 macros
{# template.html #}
{% import 'macros.html' as macros %}
{% import 'macros_override.html' as macros %}
{{ macros.a({ 'a': 'foo' }) }}
{{ macros.b({ 'b': 'bar' }) }}
Run Code Online (Sandbox Code Playgroud)
和我期望的输出:
Overridden: foo
bar
Run Code Online (Sandbox Code Playgroud)
但是b未定义.我试图将macros_override.html模板更改为:
{# macros_override.html #}
{% extends 'macros.html' %}
{% macro a(opts = {}) %}
Overridden: {{ opts.a }}
{% endmacro %}
Run Code Online (Sandbox Code Playgroud)
然后只导入覆盖模板作为宏,但a在这种情况下不会覆盖宏,我真的不知道为什么.
我可以通过其他导入以某种方式覆盖jinja中的导入宏吗?
所以在我的同事的帮助下,我明白了.
在孩子之后评估父模板
http://jinja.pocoo.org/docs/dev/faq/#my-macros-are-overridden-by-something
这意味着如果你想使用第二个选项,你只需要在父模板中检查宏是否存在.
像这样工作:
{# macros.html #}
{% if not a %}
{% macro a(opts = {}) %}
{{ opts.a }}
{% endmacro %}
{% endif %}
{% if not b %}
{% macro b(opts = {}) %}
{{ opts.b }}
{% endmacro %}
{% endif %}
Run Code Online (Sandbox Code Playgroud)
而这一个包含覆盖
{# macros_override.html #}
{% extends 'macros.html' %}
{% if not a %}{# I repeat here in case there's gonna be a double extend #}
{% macro a(opts = {}) %}
Overridden: {{ opts.a }}
{% endmacro %}
{% endif %}
Run Code Online (Sandbox Code Playgroud)
并且就像这样导入它们
{# template.html #}
{% import 'macros_override.html' as macros %}
{{ macros.a({ 'a': 'foo' }) }}
{{ macros.b({ 'b': 'bar' }) }}
Run Code Online (Sandbox Code Playgroud)
它按预期输出
Overridden: foo
bar
Run Code Online (Sandbox Code Playgroud)