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 在适当的地方使用它们,但不要在包含的文件中使用任何 blockextendsinclude 语句。 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】:

不是确切的东西,但你可以这样做(我用它来包括导航栏):

使用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,因此所有其他变量都将被忽略。

【讨论】:

以上是关于django:在包含的模板中使用块的主要内容,如果未能解决你的问题,请参考以下文章

Django 模板:通过扩展模板覆盖包含的子模板块

模板标签模板中的 Django 模板块

是否可以使用 django 的自定义模板标签在模板的其他块中插入代码?

使用 django-pygmentify 突出显示 Django 模板引擎中的内部代码块

Django 模板:翻译带有 HTML 的文本块的最佳实践

Django模板:在同一基础中使用多个块标签