Jinja 2:逃避和延伸

时间:2016-11-10 15:13:17

标签: django-templates jinja2 python-sphinx

我试图在通过Jinja2运行我的模板后输出html,然后通过Django。 {{ 'RAW' }}{% raw %}...{% endraw %}标记没有按照我的预期进行,并且没有很多关于此的文档,我的Google搜索也没有产生任何帮助。

作为示例,请考虑以下系列模板。第一个是库存Jinja2基页,需要扩展。

{# jinja_base.html #}
{% block jinja_head %}
 JINJA HEAD
{% endblock jinja_head %}
{% block jinja_body %}
 JINJA BODY
{% endblock jinja_body %}
{% block jinja_foot %}
 JINJA FOOT
{% endblock jinja_foot %}

第二个是想要扩展的股票Django模板页面。

{# django_base.html #}
{% block django_head %}
 DJANGO HEAD
{% endblock django_head %}
{% block django_body %}
 DJANGO BODY
{% endblock django_body %}
{% block django_foot %}
 DJANGO FOOT
{% endblock django_foot %}

为了扩展它们,我有一个Jinja / Django mixin模板,内容如下。我的想法是首先通过Jinja然后通过Django运行它。

{# mixin.html #}
{{ '{% extends "django_base.html" %}' }}
{% extends "jinja_base.html" %}
{{ '{% block django_head %}' }}
{% block jinja_head %}
 MIXIN HEAD
{% endblock jinja_head %}
{{ '{% endblock django_head %}' }}
{{ '{% block django_body %}' }}
{% block jinja_body %}
 MIXIN BODY
{% endblock jinja_body %}
{{ '{% endblock django_body %}' }}
{{ '{% block django_foot %}' }}
{% block jinja_foot %}
 JINJA FOOT
{% endblock jinja_foot %}
{{ '{% endblock django_foot %}' }}

在Jinja运行之后,我期待以下输出

{% extends "django_base.html" %}
{% block django_head %}
 MIXIN HEAD
{% endblock django_head %}
{% block django_body %}
 MIXIN BODY
{% endblock django_body %}
{% block django_foot %}
 JINJA FOOT
{% endblock django_foot %}

然而,我得到了以下内容。

{% extends "jinja_base.html" %}
 MIXIN HEAD
 MIXIN BODY
 JINJA FOOT

这就是嵌入Jinja转义序列中的所有Django代码都被剥离了。但是保留了第一个标签。

文档提到extends之前的任何内容都保持不变,但之后的所有内容都不是。没有解释如何最好地规避这一点,也没有解释为什么这会影响raw /转义代码。

嗯..也许我必须把延伸放在最后?

1 个答案:

答案 0 :(得分:1)

扩展模板后,必须将内容放在块之间。其他所有东西都被忽略了。所以在mixin.html

{{ '{% block django_head %}' }}   <--- ignored
{% block jinja_head %}
 MIXIN HEAD
{% endblock jinja_head %}
{{ '{% endblock django_head %}' }} <--- ignored

第一行和最后一行在jinja_head块之外,因此将被忽略。

正确的方法很简单,只需将Django线放在Jinja的块之间,例如:

{% block jinja_head %}
{{ '{% block django_head %}' }}
MIXIN HEAD
{{ '{% endblock django_head %}' }}
{% endblock jinja_head %}

结果:

{% block django_head %} 
MIXIN HEAD 
{% endblock django_head %}

对于{{ '{% extends "django_base.html" %}' }},只需在jinja_base.html中定义一个空块,您可以使用Django扩展线在mixin.html中覆盖它。完整的例子:

jinja_base.html

{# jinja_base.html #}

{% block django_extends %}
{% endblock django_extends %}

{% block jinja_head %}
JINJA HEAD
{% endblock jinja_head %}

{% block jinja_body %}
JINJA BODY
{% endblock jinja_body %}

{% block jinja_foot %}
JINJA FOOT
{% endblock jinja_foot %}

mixin.html

{# mixin.html #}
{% extends "jinja_base.html" %}

{% block django_extends %}
{{ '{% extends "django_base.html" %}' }}
{% endblock django_extends %}

{% block jinja_head %}
{{ '{% block django_head %}' }}
MIXIN HEAD
{{ '{% endblock django_head %}' }}
{% endblock jinja_head %}

{% block jinja_body %}
{{ '{% block django_body %}' }}
 MIXIN BODY
{{ '{% endblock django_body %}' }}
{% endblock jinja_body %}

{% block jinja_foot %}
{{ '{% block django_foot %}' }}
 JINJA FOOT
{{ '{% endblock django_foot %}' }}
{% endblock jinja_foot %}

通过这种方式,您将看到Jinja渲染后的预期结果:

{% extends "django_base.html" %}

{% block django_head %}
 MIXIN HEAD
{% endblock django_head %}

{% block django_body %}
 MIXIN BODY
{% endblock django_body %}

{% block django_foot %}
 JINJA FOOT
{% endblock django_foot %}