2011-06-21 40 views
2

有没有办法让内容块具有相同的名称?Django:具有相同名称的嵌套内容块

base.html文件:

这是主要布局的模板。

<html> 

    ... 

    {% block content %} 

    {% endblock %} 

    ... 

</html> 

base_side_left.html:

这是主要布局+侧边栏左侧的模板。

{% extends 'base.html' %} 

{% block content %} 

    <div class='sidebar'> 
    </div> 

    {% block content %} 

    //This doesn't work because you can't have blocks with the same name// 

    {% endblock %} 

{% endblock 

我为什么我问这几个原因:

  1. 可以很容易地更改页面的父,而无需更改内容块的名称。
  2. 我不必为我的街区想出名字。像内容的内容,侧边栏的内容,等

我得到了这个,我不喜欢两种解决方案,因为他们是不会干:

  1. 让侧边栏的部分,并将其纳入你需要的模板。
  2. 将所有内容添加到基本模板并覆盖不需要的块。

如果这是不可能与Django模板我可以做这样的事情与其他模板引擎?

小更新:

template diagram

所以我想要做的是能够在模板树四处移动模板,而无需到太多的麻烦。这是不可能的,虽然没有为我的内容块提出聪明的名字,但我想我反正添加了这个漂亮的图。

+0

你能解释一下为什么你认为这是一个坏理念? – Pickels

+0

Mike在 – kieran

回答

6

不,你不能。来自Django docs on template inheritance

您无法在同一个模板中定义具有相同名称的多个{% block %}标记。这种限制的存在是因为块标签在“两个”方向上工作。也就是说,块标记不仅仅提供了一个要填充的洞 - 它还定义填充父项中的洞的内容。如果在模板中有两个名称相似的{% block %}标记,则该模板的父级将不知道要使用哪个块的内容。

我不清楚你为什么要这样做。

很容易更改页面的父级,而不必更改内容块的名称。

只有一个{% block %}标记具有给定的名称,并且只有一个{% extends %}标记。我没有看到任何困难。

我不必为自己的街区想出名字。像内容内容,边栏内容等

任何维护您的代码的人都会很快失去跟踪哪些content块有效并且感到困惑。此外,这些名字应该与{% block %}应该做的事有关。所以我想知道为什么你会有两个模板,一个包含另一个模板,其模块完全相同。

docs还有一点:

如果你发现自己在许多模板复制内容,这可能意味着你应该将在父模板内容到{%块%}。

这可让您将重复标记设置为默认值,并且可以在需要的地方覆盖它。

这可能是有帮助的,太:

如果你需要得到该块的父模板的内容,该{{ block.super }}变量会做的伎俩。如果你想添加父块的内容而不是完全覆盖父块的内容,这很有用。使用{{ block.super }}插入的数据将不会自动转义(请参阅下一节),因为它已经在父模板中被转义(如有必要)。

从我可以告诉,这可能是你最好的选择:

让侧边栏的部分,包括它在您需要的模板。

这是不是DRY?你必须重复{% include %}标签?

我认为有一个更好的设计解决方案可以为你工作,但是你还没有给出足够的信息来帮助我进一步提高。

编辑:看看你的例子,你可以用一个模板做所有 CSS会在这里照顾你。

page_template.html:

<!DOCTYPE html PUBLIC -- ... --> 
<html> 
<head> 
    <!-- ... other header fields ... --> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
    <base href="{{ host }}{{ root }}{{ path }}" /> 
    <title>{% block title %}Untitled{% endblock %}</title> 
    <link rel="icon" type="image/png" 
     href="{{ root }}static/images/favicon.png" /> 
    <link rel="stylesheet" type="text/css" 
     href="{{ root }}static/css/general.css" /> 
    <!-- other header fields here --> 
{% block head %}{% endblock %} 
</head> 
<body class="{% block page_class %}no_sidebar{% endblock %}"> 
    <div id="page_header"> 
     <!-- page heading here --> 
    </div> 
    <div id="sidebar"> 
     {% block sidebar %}<!-- default sidebar here -->{% endblock %} 
    </div> 
    <div id="banner"> 
     {% block banner %}{% endblock %} 
    </div> 
    <div id="content"> 
     {% block content %}{% endblock %} 
    </div> 
</body> 
</html> 

general.css:

body.no_sidebar div#sidebar, 
div#banner 
{ 
    display: none; 
} 

div#sidebar 
{ 
    width: 20%; 
} 

body.with_sidebar div#sidebar 
{ 
    float: left; 
} 

body.with_banner div#banner 
{ 
    display: block; 
} 

body.right_sidebar div#sidebar 
{ 
    float: right; 
} 

那么你的页面只是看起来像,在你的例子顺序:

plain_old_page。HTML:

{% extends base.html %} 

{% block content %} 
    <!-- content goes here --> 
{% endblock %} 

page_with_left_sidebar.html:

{% extends base.html %} 
{% block page_class %}with_sidebar{% endblock %} 

{% block sidebar %} 
    <!-- sidebar goes here, if different from default --> 
    <!-- otherwise omit this section --> 
{% endblock %} 

{% block content %} 
    <!-- content goes here --> 
{% endblock %} 

page_with_left_sidebar_and_banner.html:

{% extends base.html %} 
{% block page_class %}with_sidebar with_banner{% endblock %} 

{% block sidebar %} 
    <!-- sidebar goes here, if different from default --> 
    <!-- otherwise omit this section --> 
{% endblock %} 

{% block banner %} 
    <!-- banner goes here --> 
{% endblock %} 

{% block content %} 
    <!-- content goes here --> 
{% endblock %} 

page_with_right_sidebar.html:

{% extends base.html %} 
{% block page_class %}right_sidebar{% endblock %} 

{% block sidebar %} 
    <!-- sidebar goes here, if different from default --> 
    <!-- otherwise omit this section --> 
{% endblock %} 

{% block content %} 
    <!-- content goes here --> 
{% endblock %} 
+1

以下覆盖了我的大部分理由好像我在问一些奇怪的事情。我对IRC有类似的反应。我在其他语言中使用这种技术,其中模板支持具有相同名称的嵌套块,我认为它的工作非常好。我不认为其他人维护它是一个大问题。他们只需遵循延伸到基本模板的方式。包含标签不是干这种方式,因为我不得不重复它。对于一个侧边栏它是可行的,但如果你有其他共享的部分。无论如何,我在这里有限的空间,所以我会用剩下的空间感谢您花时间回答:谢谢:) – Pickels

+1

您可以随时编辑问题以提供更多细节。那里没有空间限制。我仍然认为有一个更好的方法来完成你想做的事情,*如果我有一些想法你想做什么。* –

+0

更新了一些问题,但我认为你的答案已经告诉我,这是不可能的,我想要的。 – Pickels