django:在包含的模板中使用块
Posted
技术标签:
【中文标题】django:在包含的模板中使用块【英文标题】:django: using blocks in included templates 【发布时间】:2012-03-26 20:44:42 【问题描述】:我有一些 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 中的extends 有一些拼写错误,我刚刚更正了。
可能不是很清楚,但上面的代码更像是描述我想要的结果的伪代码。总之,
我想在我的 模板。 这些模式就像盒子,你可以把整片html 其中的内容。所以上下文变量可能有点太有限了 我的目的【问题讨论】:
似乎从未调用过template_level2.html
。如果您 include
一些代码块,则不需要使用 block
语句,因为您将包含您想要的时间和内容
您好,快速重载! template_level2.html
是模板的最后一级,因此它不包含/扩展任何地方。通过在template_level2.html
中调用% block %
语句,我打算将内容放入reusable_pattern_template.html
,在template_level2.html
中使用
问题:为什么不使用 django-generic-flatblocks ?这是一个很棒的应用程序,提供了一个很好的模式。
template_level2.html 不带引号被解释为必须评估为字符串或模板对象的变量。阅读更多关于extends
【参考方案1】:
Django 不处理包含文件中的块。
include 标签应该被认为是“渲染这个子模板并包含 HTML”的实现,而不是“解析这个子模板并包含它的内容,就好像它是父模板的一部分一样”。这意味着包含的模板之间没有共享状态——每个包含都是一个完全独立的渲染过程。 (Django template tag documentation)
【讨论】:
视图中的变量仍然是共享和解析的。 上下文也被赋予包含的模板(这可能与上面的评论相同,但'context'比Variables From View更容易识别。) 有帮助的解释,但是 is 是否有标签或其他方法可以实现 OP 所希望的?我也希望能够包含一个模板,并且仍然能够使用模板继承 @Chris Pratt 如果我想在脚本标签中包含一个具有一些“模型绑定”JS 行为的页面,并且我不希望 2021年,有办法处理包含文件中的块吗?【参考方案2】:我遇到了这个问题并最终做出了以下妥协,希望其他人会发现它有用。它依赖于在子模板中使用with
块。
base.html 想要重用一个常见的 nav.html 包含,但定义了一些块,其中 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>
[...]
include 模板依赖于一个名为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】:似乎最终模板正在尝试扩展自身(如果它在引号中)。
你真的不需要那么复杂。它实际上要简单得多。
基本模板应该包含模板的骨架,然后您可以对其进行扩展以进行自定义。对于您不想包含在每个视图中的可重用代码块,include
在适当的地方使用它们,但不要在包含的文件中使用任何 block
、extends
或 include
语句。 Django 不会解析这些,但仍然可以使用从视图传递的context variable
。
【讨论】:
【参考方案4】:简而言之,您可以在计划包含的任何模板中创建变量,例如
localcontent
然后在包含模板的任何位置分配这些变量,例如
% include "name_snippet.html" with localcontent="Actual content" %
【讨论】:
【参考方案5】:您可以将 reusable_pattern_template 拆分为开始和结束模板。然后在 level1 你可以去 include begin, block, include end。
或者,您可以将模板名称作为上下文变量传递给 reusable_pattern_template,然后将其包含在 reusable_pattern_template 中。这将需要在您的示例中更改 level1 和 level2 之间的关系,但通常更强大。
【讨论】:
【参考方案6】:不是确切的东西,但你可以这样做(我用它来包括导航栏):
使用with
和only
snippet.html
:
<div>
listItem1 listItem2 ... listItemN
</div>
index.html
:
% include 'snippet.html' with listItem1='<li>HOME</li>' listItem2 ='<li>ABOUT</li>' only %
由于我们在 listItem2 之后使用了only
,因此所有其他变量都将被忽略。
【讨论】:
以上是关于django:在包含的模板中使用块的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 django 的自定义模板标签在模板的其他块中插入代码?