在Jinja2中,如何将宏与块标签结合使用?

Rey*_*Rey 10 python django templates django-templates jinja2

我是一名前端开发人员,而且我一直试图有效地使用Jinja2.我想调整当前站点,使其具有使用继承的多个基本模板,它完全使用块标记替换内容并覆盖它,并使用宏来支持传递参数.

我的基本模板包含此代码(为简单起见而编辑):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
{% from "foo.html" import macro1, macro2, macro3 %}
{% macro base_template(title=none, arg2=none, urls={}, arg3=false) %}
<html>
  <title>{{ title }} | Site.com</title>
  ....
  {{ caller() }}
  ....
</html>
{% endmacro %}

{% block content %}{% endblock %}
Run Code Online (Sandbox Code Playgroud)

我扩展它的页面看起来像这样:

{% extends "base.html" %}
{% block content %}
{% call base_template(title="home", arg2="active", arg3="true") %}
(html code here)
{% endcall %}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

所以基本上所有页面都扩展了基础,它们调用宏并将参数传递给该宏.我不太了解这一切,但重点是这允许默认值和一定程度的灵活性,不需要重新定义整个块:它提供了一定程度的灵活性和功能.这再次大大简化了.

唯一的问题是,这否定了我使用块的能力.宏是为了灵活性,但是对于块,我有能力完全覆盖某些东西,或者使用它的父项内容并添加它,我不能用宏来做(至少我不认为).问题是,我不能用块包装东西,否则它们不会看到宏中的值.例如,这样做:

{% block title %}<title>{{ title }} | Site.com</title>{% endblock %}
Run Code Online (Sandbox Code Playgroud)

会失败,因为它会说标题未定义.

最终,我正在寻找一种方法来利用块的功能和组织方面,但仍然能够利用宏的逻辑和简洁性.如果有人能帮我解决这个问题,我会非常感激.

Lea*_*orm 20

块只能在模板的顶层定义.如果扩展模板,set则可以从正在扩展的模板访问使用标记在子模板中设置的任何值.例如,如果您有一个名为的模板layout.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
  <title>{{ title }} | Site.com</title>
  ....
  {% block content %}{% endblock content %}
  ....
</html>
Run Code Online (Sandbox Code Playgroud)

你有这个子模板,index.html:

{% extends "layout.html" %}
{% set title = 'Homepage' %}
{% block content %}
(html code here)
{% endblock content %}
Run Code Online (Sandbox Code Playgroud)

然后title在父级中的引用将解析为'Homepage'.您可以使用任何类型的变量执行此操作.对于你正在做的事情,我认为不需要宏 - 如果你利用这个功能并很好地放置块,就布局而言,你将能够完成你需要做的所有事情. .如果你想知道何时使用Jinja2的各种功能,我会看一下由一个Jinja2作者编写的Plurk Solace使用的一些模板.