Django:具有相同名称的嵌套内容块 [英] Django: nested content blocks with the same name

查看:47
本文介绍了Django:具有相同名称的嵌套内容块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法让内容块具有相同的名称?

Is there a way to have content blocks with the same name?

base.html:

这是具有主要布局的模板.

This is the template with the main layout.

<html>

  ...

  {% block content %}

  {% endblock %}

  ...

</html>

base_side_left.html:

这是模板,左侧是主布局+侧边栏.

This is the template with the main layout + sidebar on the left.

{% 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

我有几个理由要问这个问题:

I have a few reason why I am asking this:

  1. 无需更改内容块的名称即可轻松更改页面的上级.
  2. 我不必为我的积木想出名字.像content-content,sidebar-content等

我有两个我不喜欢的解决方案,因为它们不是干的:

I got two solutions for this which I don't like because they ain't DRY:

  1. 将侧边栏设为部分,并将其包含在所需的模板中.
  2. 将所有内容添加到基本模板中,并覆盖不需要的那些块.

如果Django模板无法做到这一点,我可以使用其他模板引擎来做类似的事情吗?

If this isn't possible with Django Template can I do something like this with an other templating engine?

小更新:

所以我要做的是能够在模板树中随意移动模板.虽然没有为内容块提供智能名称是不可能的,但是我认为我还是要添加这个漂亮的图表.

So what I want to do is to be able to move the templates around in the template tree without to much hassle. It's not possible though without coming up with smart names for my content blocks but I thought I add this pretty diagram anyways.

推荐答案

不,您不能.从关于模板继承的Django文档:

您不能在同一模板中定义多个具有相同名称的 {%block%} 标签.存在此限制的原因是,块标签在两个"方向上均有效.也就是说,block标签不仅提供填充孔,还定义了填充 parent 中孔的内容.如果模板中有两个名称相似的 {%block%} 标签,则该模板的父级将不知道要使用哪个块内容.

you can't define multiple {% block %} tags with the same name in the same template. This limitation exists because a block tag works in "both" directions. That is, a block tag doesn't just provide a hole to fill -- it also defines the content that fills the hole in the parent. If there were two similarly-named {% block %} tags in a template, that template's parent wouldn't know which one of the blocks' content to use.

我不清楚您为什么要这么做.

I'm not clear on why you want to do this.

无需更改内容块的名称即可轻松更改页面的父级.

It's easy to change the parent of a page without having to change the name of the content blocks.

只有一个具有给定名称的 {%block%} 标签,并且也只有一个 {%extended%} 标签.我认为难度没有任何区别.

There's only one {% block %} tag with a given name, and there's only one {% extends %} tag as well. I don't see any difference in difficulty.

我不必为我的积木想出名字.像content-content,sidebar-content等

I don't have to come up with names for my blocks. Like content-content, sidebar-content, etc

任何维护您代码的人都将很快失去对哪个 content 块有效的了解,并感到困惑.此外,名称应该与 {%block%} 应该具有的功能有关.因此,我想知道为什么会有两个模板,一个包含另一个模板,而这些模板具有完全相同的块.

Anyone maintaining your code will quickly lose track of which content block is effective and get confused. Besides, the names should have something to do with what the {% block %} is supposed to do. So I'm wondering why you'd have two templates, one including another, with blocks that are exactly the same.

文档中的另一点:

如果您发现自己在多个模板中复制内容,则可能意味着您应该将该内容移至父模板中的{%block%}.

If you find yourself duplicating content in a number of templates, it probably means you should move that content to a {% block %} in a parent template.

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

This lets you make the duplicated markup the default, and you can override it in those places where needed.

这也可能有帮助:

如果您需要从父模板中获取块的内容,则可以使用 {{block.super}} 变量来完成.如果要添加到父块的内容而不是完全覆盖它,这将很有用.使用 {{block.super}} 插入的数据将不会自动转义(请参阅下一节),因为如果需要,在父模板中已经转义了该数据.

If you need to get the content of the block from the parent template, the {{ block.super }} variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }} will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.

据我所知,这可能是您最好的选择:

From what I can tell, this is probably your best choice:

将侧边栏部分化,并将其包含在所需的模板中.

Make the sidebar a partial and include it in the templates you need.

这怎么不干?您必须重复 {%include%} 标记吗?

How is this not DRY? You have to repeat the {% include %} tag?

我认为,有一个更好的设计解决方案将为您服务,但是您没有获得足够的信息以帮助我.

I think there's a better design solution that would work for you, but you haven't given enough info on what you're trying to accomplish for me to help further.

编辑:在您的示例中,您可以使用单个模板完成所有. CSS将在这里为您服务.

Looking at your example, you can do all that with a single template. CSS will take care of you here.

page_template.html:

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:

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;
}

然后按照您的示例顺序,您的页面看起来就像这样:

Then your pages just look like, in the order of your examples:

plain_old_page.html:

plain_old_page.html:

{% extends base.html %}

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

page_with_left_sidebar.html:

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:

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:

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 %}

这篇关于Django:具有相同名称的嵌套内容块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆