为什么Django的原始作者包含标签?

时间:2022-12-22 05:31:42

In this excellent Google Tech Talk by Jacob Kaplan-Moss, Jacob says that they added support for the include template tag despite previous dogmatic objections, and says that people shouldn't use it.

在Jacob Kaplan-Moss的优秀Google技术讲座中,雅各布表示,尽管之前存在教条主义的反对意见,但他们仍然支持包含模板标签,并表示人们不应该使用它。

Does anyone know why? A quick search didn't show anything that would explain why. There's nothing relevant in the now-fixed ticket where support for an include tag was added. I use include tags liberally to avoid repeating myself, which seems like a good idea, but maybe I'm missing some core reason why those who know think it's bad.

有谁知道为什么?快速搜索没有显示可以解释原因的任何内容。现在修复的票证中没有任何相关内容,其中添加了对包含标签的支持。我*地使用包含标签以避免重复自己,这似乎是一个好主意,但也许我错过了一些核心原因,为什么那些知道认为它是坏的。

1 个解决方案

#1


9  

I suppose he wants to encourage template reuse by inheritance (using extends) rather than by composition. Perhaps the implication is that if you can't organise your templates this way, the dogmatic opinion is that your site is organised poorly. (For example, if you are reusing a navigation menu, shouldn't it always be in the same place in the page structure? Why should each individual page decide where to put it?)

我想他希望通过继承(使用extends)而不是通过组合来鼓励模板重用。也许这意味着如果你不能以这种方式组织你的模板,那么教条主义的观点是你的网站组织得很糟糕。 (例如,如果您正在重复使用导航菜单,它是否应该始终位于页面结构中的相同位置?为什么每个页面都要决定放置它的位置?)

By the way, using include doesn't do much to help you stay DRY, because any context that the included template requires must be passed from all the views that use it.

顺便说一下,使用include并不能帮助你保持DRY,因为包含的模板所需的任何上下文必须从使用它的所有视图中传递。

By contrast, using a custom inclusion template tag allows you to execute arbitrary Python code at the point where the tag is included, rather than in the view (or by shoving it into a model just to make it easier to access in the template).

相比之下,使用自定义包含模板标记允许您在包含标记的位置执行任意Python代码,而不是在视图中执行(或者通过将其推送到模型中以使其更容易在模板中访问)。

As a trivial example, I wanted to show a list of users' avatars. Using include, it looks like this:

作为一个简单的例子,我想显示用户的头像列表。使用include,它看起来像这样:

{% for user in users %}
    {% with user.gravatar_url as avatar_url %}
        {% include "foo/bar/avatar.html" %}
    {% endwith %}
{% endfor %}

With a custom tag:

使用自定义标记:

{% for user in users %}
    {% gravatar user.email %}
{% endfor %}

Using the custom inclusion tag meant that the Gravatar hashing logic no longer had to be a concern of the User model, nor of the view function.

使用自定义包含标记意味着Gravatar散列逻辑不再是User模型和视图函数的关注点。


This said, I think are are some situations where you inevitably have similar data in the context of multiple templates, you don't need to do anything fancy with it, you just want to display some of its attributes so you don't want to write a function to make it work.

这说,我认为在某些情况下你不可避免地在多个模板的上下文中有类似的数据,你不需要做任何花哨的事情,你只想显示它的一些属性,所以你不想写一个函数让它工作。

For example, I wrote a blog application (who hasn't?) which had two types of archive view: a basic sequential, X-posts-per-page one, and a monthly archive view. Both templates obviously had a list of posts in their context, both used exactly the same summary template fragment to show a title and excerpt from each post, but each template presented them in a slightly different context. So I used:

例如,我写了一个博客应用程序(谁没有?),它有两种类型的归档视图:基本顺序,每页X-posts和每月归档视图。两个模板显然都在其上下文中有一个帖子列表,两者都使用完全相同的摘要模板片段来显示每个帖子的标题和摘录,但每个模板在略有不同的上下文中显示它们。所以我用过:

{# in archive_index.html #}
{% extends "base.html" %}

{# some stuff specific to sequential archives here #}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{# probably more stuff specific to sequential archives #}

And...

和...

{# in archive_monthly.html #}
{% extends "base.html" %}

{# some stuff specific to monthly archives here #}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{# probably more stuff specific to monthly archives #}

It really seems that in this case, composition makes more sense than inheritance. In fact it was difficult at first to imagine how inheritance would work here at all. Well, it's still possible:

在这种情况下,组合似乎比继承更有意义。事实上,一开始很难想象继承在这里是如何起作用的。嗯,它仍然可能:

{# in base_archive.html #}
{% extends "base.html" %}

{% block archive_header %}{% endblock %}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{% block archive_pagination %}{% endblock %}

Now, the two different archives extend this and just inject their unique stuff into the blocks:

现在,两个不同的档案扩展了这一点,只是将他们独特的东西注入到块中:

{# in archive_monthly.html #}
{% extends "base_archive.html" %}

{% block archive_header %}
    <h1>Archive for {{ month }}</h1>
{% endblock %}

{% block archive_pagination %}
    {# previous/next month links here #}
{% endblock %}

I'll leave imagining what archive_index.html looks like as an exercise for the (no doubt bored) reader.

我会想象archive_index.html看起来像是(无疑是无聊的)读者的练习。

Phew! It feels smart to have come up with a way of doing the same thing using both composition and inheritance, but is the latter just bending over backwards to conform to the dogma that Jacob Kaplan-Moss mentioned?

唷!想出一种使用组合和继承来做同样事情的方法感觉很聪明,但是后者只是向后弯腰以符合Jacob Kaplan-Moss提到的教条吗?

Having just watched the video (yes, all 1 hour 5 minutes of it, just so I could finish answering this question), I don't think Jacob would be enormously bothered. It sounded like an off-the-cuff comment, maybe a reference to which technique you ought to consider first.

刚观看了视频(是的,所有1小时5分钟的时间,我完全可以回答这个问题),我认为雅各布不会受到太大的打扰。这听起来像是一个袖手旁观的评论,也许是你应该首先考虑哪种技术的参考。

#1


9  

I suppose he wants to encourage template reuse by inheritance (using extends) rather than by composition. Perhaps the implication is that if you can't organise your templates this way, the dogmatic opinion is that your site is organised poorly. (For example, if you are reusing a navigation menu, shouldn't it always be in the same place in the page structure? Why should each individual page decide where to put it?)

我想他希望通过继承(使用extends)而不是通过组合来鼓励模板重用。也许这意味着如果你不能以这种方式组织你的模板,那么教条主义的观点是你的网站组织得很糟糕。 (例如,如果您正在重复使用导航菜单,它是否应该始终位于页面结构中的相同位置?为什么每个页面都要决定放置它的位置?)

By the way, using include doesn't do much to help you stay DRY, because any context that the included template requires must be passed from all the views that use it.

顺便说一下,使用include并不能帮助你保持DRY,因为包含的模板所需的任何上下文必须从使用它的所有视图中传递。

By contrast, using a custom inclusion template tag allows you to execute arbitrary Python code at the point where the tag is included, rather than in the view (or by shoving it into a model just to make it easier to access in the template).

相比之下,使用自定义包含模板标记允许您在包含标记的位置执行任意Python代码,而不是在视图中执行(或者通过将其推送到模型中以使其更容易在模板中访问)。

As a trivial example, I wanted to show a list of users' avatars. Using include, it looks like this:

作为一个简单的例子,我想显示用户的头像列表。使用include,它看起来像这样:

{% for user in users %}
    {% with user.gravatar_url as avatar_url %}
        {% include "foo/bar/avatar.html" %}
    {% endwith %}
{% endfor %}

With a custom tag:

使用自定义标记:

{% for user in users %}
    {% gravatar user.email %}
{% endfor %}

Using the custom inclusion tag meant that the Gravatar hashing logic no longer had to be a concern of the User model, nor of the view function.

使用自定义包含标记意味着Gravatar散列逻辑不再是User模型和视图函数的关注点。


This said, I think are are some situations where you inevitably have similar data in the context of multiple templates, you don't need to do anything fancy with it, you just want to display some of its attributes so you don't want to write a function to make it work.

这说,我认为在某些情况下你不可避免地在多个模板的上下文中有类似的数据,你不需要做任何花哨的事情,你只想显示它的一些属性,所以你不想写一个函数让它工作。

For example, I wrote a blog application (who hasn't?) which had two types of archive view: a basic sequential, X-posts-per-page one, and a monthly archive view. Both templates obviously had a list of posts in their context, both used exactly the same summary template fragment to show a title and excerpt from each post, but each template presented them in a slightly different context. So I used:

例如,我写了一个博客应用程序(谁没有?),它有两种类型的归档视图:基本顺序,每页X-posts和每月归档视图。两个模板显然都在其上下文中有一个帖子列表,两者都使用完全相同的摘要模板片段来显示每个帖子的标题和摘录,但每个模板在略有不同的上下文中显示它们。所以我用过:

{# in archive_index.html #}
{% extends "base.html" %}

{# some stuff specific to sequential archives here #}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{# probably more stuff specific to sequential archives #}

And...

和...

{# in archive_monthly.html #}
{% extends "base.html" %}

{# some stuff specific to monthly archives here #}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{# probably more stuff specific to monthly archives #}

It really seems that in this case, composition makes more sense than inheritance. In fact it was difficult at first to imagine how inheritance would work here at all. Well, it's still possible:

在这种情况下,组合似乎比继承更有意义。事实上,一开始很难想象继承在这里是如何起作用的。嗯,它仍然可能:

{# in base_archive.html #}
{% extends "base.html" %}

{% block archive_header %}{% endblock %}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{% block archive_pagination %}{% endblock %}

Now, the two different archives extend this and just inject their unique stuff into the blocks:

现在,两个不同的档案扩展了这一点,只是将他们独特的东西注入到块中:

{# in archive_monthly.html #}
{% extends "base_archive.html" %}

{% block archive_header %}
    <h1>Archive for {{ month }}</h1>
{% endblock %}

{% block archive_pagination %}
    {# previous/next month links here #}
{% endblock %}

I'll leave imagining what archive_index.html looks like as an exercise for the (no doubt bored) reader.

我会想象archive_index.html看起来像是(无疑是无聊的)读者的练习。

Phew! It feels smart to have come up with a way of doing the same thing using both composition and inheritance, but is the latter just bending over backwards to conform to the dogma that Jacob Kaplan-Moss mentioned?

唷!想出一种使用组合和继承来做同样事情的方法感觉很聪明,但是后者只是向后弯腰以符合Jacob Kaplan-Moss提到的教条吗?

Having just watched the video (yes, all 1 hour 5 minutes of it, just so I could finish answering this question), I don't think Jacob would be enormously bothered. It sounded like an off-the-cuff comment, maybe a reference to which technique you ought to consider first.

刚观看了视频(是的,所有1小时5分钟的时间,我完全可以回答这个问题),我认为雅各布不会受到太大的打扰。这听起来像是一个袖手旁观的评论,也许是你应该首先考虑哪种技术的参考。