django:在包含的模板中使用块

时间:2012-03-09 11:35:12

标签: django django-templates

我有一些html结构可以在很多不同的地方重用。它与整体模板不同,所以我不能扩展它,它也可以用来包含复杂的内容,所以我不认为将它定义为模板标签做得很好。下面是一些描述我想要的结果的伪代码,当使用template_level2.html时,您可以通过调用其中的块轻松地将内容放入reusable_pattern_template。如果我使用此代码,则您在template_level_2.html的“实际内容”中所写的内容将不会显示。我应该怎么处理这个?

base.html文件

<html>
<head></head>
<body>
{% block content %}{% endblock %}
</body>
</html>

template_level1.html

{% extends 'base.html' %}
{% block content %}
  Something here...
  {% include 'reusable_pattern_template.html' %}
  Something else here...
{% endblock %}

reusable_pattern_template.html

<div>
  <div>
    <div>
      {% block local_content %}{% endblock %}
    </div>
   </div>
</div>

template_level2.html

{% extends 'template_level1.html' %}
{% block local_content %}
  Actual content here...
{% endblock %}

更新 抱歉,template_level2.html中的扩展有一些拼写错误,我刚刚纠正了它。

可能不是很清楚,但上面的代码更像是一个描述我想要的结果的伪代码。简而言之,

  • 我想在我的网站中包含一小块可重复使用的html模式 模板。
  • 这些模式就像盒子,你可以把整个html片段 其中的内容。因此,上下文变量可能有点过于有限 我的目的

6 个答案:

答案 0 :(得分:48)

Django不处理包含文件中的块。

  

include标记应该被视为“渲染此子模板并包含HTML”的实现,而不是“解析此子模板并将其内容包含在内,就好像它是父节点的一部分”。这意味着包含的模板之间没有共享状态 - 每个包含都是完全独立的渲染过程。 (Django template tag documentation

答案 1 :(得分:3)

似乎最终模板试图扩展自己(如果它在引号中)

你真的不需要太多的复杂性。它实际上非常简单。

基本模板应该包含模板的骨架,然后您可以对其进行扩展以进行自定义。对于您不希望包含在每个视图中的可重用代码块,include在适当的位置使用它们,但不要在其中使用任何blockextendsinclude语句包含的文件。 Django不会解析那些,但仍然可以使用从视图传递的context variable

答案 2 :(得分:2)

我遇到了这个问题并最终达成了以下妥协,希望其他人可能会觉得它很有用。它依赖于在子模板中使用with块。

base.html 希望重用常见的 nav.html include,但要定义一些块,其中 nav.html 中的变量可能会被覆盖通过儿童模板。

<!-- base.html: -->
<html>
  [...]
  <nav class="desktop">
    {% block desktop_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]
  <nav class="mobile">
    {% block mobile_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]

包含模板取决于名为selected的变量,默认情况下 base.html 未定义该变量:

<!--includes/nav.html:-->
<a href="/about/" class="{% if selected == 'about' %}selected{% endif %}">About</a>
<a href="/people/" class="{% if selected == 'people' %}selected{% endif %}">People</a>
<a href="/contact/" class="{% if selected == 'contact' %}selected{% endif %}">Contact</a>

但子页面可以覆盖该值,如下所示:

<!--about.html:-->
{% extends "base.html" %}
{% block desktop_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}
{% block mobile_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}

所以,不完美,我仍然必须有两个单独的块并使用这些with块两次,但它允许我覆盖父模板中include块中的变量。

答案 3 :(得分:0)

您可以将reusable_pattern_template拆分为开始和结束模板。然后在level1中你可以包括begin,block,include end。

或者,您可以将模板名称作为上下文变量传递给reusable_pattern_template,然后将其包含在reusable_pattern_template中。这将需要更改示例中level1和level2之间的关系,但通常更强大。

答案 4 :(得分:0)

简而言之,您可以在计划包含的模板中创建变量。

{{ localcontent }}

然后在包含模板的任何地方分配这些变量,例如

{% include "name_snippet.html" with localcontent="Actual content" %}

答案 5 :(得分:0)

不完全是这样,但你可以这样做(我用它来包含导航栏):

使用 withonly

snippet.html

<div>
  {{ listItem1 }}{{ listItem2 }}...{{ listItemN }}
</div>

index.html

{% include 'snippet.html' with listItem1='<li>HOME</li>' listItem2 ='<li>ABOUT</li>' only %}

由于我们在 listItem2 之后使用了 only,因此所有其他变量都将被忽略。