The block tag has multiple meanings

1 view
Skip to first unread message

Antonis Christofides

unread,
Jun 27, 2008, 10:33:13 AM6/27/08
to django-d...@googlegroups.com
Hi,

There are essentially two things that you can do with a block:
(1) define it (or redefine it); and (2) insert it somewhere in a
template. The block tag thus performs different functions depending
on circumstances:
* If a block tag with the same name exists in an inherited
template, then the block tag merely (re)defines the block.
* If no block tag with the same name is inherited, then the block tag
at the same time defines the block AND inserts it in the template.

In my opinion, having two substantially different operations under one
label is a cause for confusion. Explicit is better than implicit. I
wonder whether it would be better the distinguish the functionality in
"insblock" and "defblock":

{% defblock myblock %}
This is myblock's definition. Possibly re-definition if the block
has already been defined in an inherited template. It does not
insert the block in the template.
{% enddefblock %}

{% insblock myblock %} {# This inserts myblock here. #}

{% defblock myblock2 insert %}
This is a shortcut: defines myblock2 and inserts it at the same time.
It's the same as the existing topmost block tag. Child templates
should allow it only inside other blocks, otherwise it doesn't
make sense.
{% enddefblock %}

{% block myblock3 %}
This is the old, deprecated block tag, existing for backwards
compatibility. It is not clear what it means.
{% endblock %}

I think that this would solve
http://code.djangoproject.com/ticket/4529 and other similar requests
in a much more natural and intuitive manner. In addition, the absense
of an insblock (or reuse-block) has resulted in my using strange and
unintuitive techniques in my templates (I wanted to define small
blocks in a base template and insert them in different order in child
templates - and "include" would create an undesired mess of many
files). When I tried to find a solution and see what other people had
said about that, I understood that the block tag is double-faced and
confusing.

Patryk Zawadzki

unread,
Jun 27, 2008, 10:52:40 AM6/27/08
to django-d...@googlegroups.com
On Fri, Jun 27, 2008 at 4:33 PM, Antonis Christofides
<ant...@itia.ntua.gr> wrote:
>
> Hi,
>
> There are essentially two things that you can do with a block:
> (1) define it (or redefine it); and (2) insert it somewhere in a
> template. The block tag thus performs different functions depending
> on circumstances:
> * If a block tag with the same name exists in an inherited
> template, then the block tag merely (re)defines the block.
> * If no block tag with the same name is inherited, then the block tag
> at the same time defines the block AND inserts it in the template.
>
> In my opinion, having two substantially different operations under one
> label is a cause for confusion. Explicit is better than implicit. I
> wonder whether it would be better the distinguish the functionality in
> "insblock" and "defblock":

No, please, don't. The master template has no place to "predefine" the
blocks as it's structure is outputted verbatim. Child templates on the
other hand have no need to define blocks outside of other blocks so
it's pretty much useless and prone to infinite loops (insert a parent
block in a sub-sub-sub-child block for example).

--
Patryk Zawadzki
PLD Linux Distribution

Malcolm Tredinnick

unread,
Jun 27, 2008, 9:19:34 PM6/27/08
to django-d...@googlegroups.com

On Fri, 2008-06-27 at 17:33 +0300, Antonis Christofides wrote:
> Hi,
>
> There are essentially two things that you can do with a block:
> (1) define it (or redefine it); and (2) insert it somewhere in a
> template. The block tag thus performs different functions depending
> on circumstances:
> * If a block tag with the same name exists in an inherited
> template, then the block tag merely (re)defines the block.
> * If no block tag with the same name is inherited, then the block tag
> at the same time defines the block AND inserts it in the template.

I think this is a mischaracterisation. A block is *always* inserted at
the place it is first declared. Its contents can be defined by a child
template (via the 'extends' mechanism), but that's all. The base
template specifies location and default content; child templates can
replace the content. It's not really that confusing. I don't think a
change is necessary here.

Malcolm


Ludvig Ericson

unread,
Jun 28, 2008, 4:58:07 AM6/28/08
to django-d...@googlegroups.com
On Fri, Jun 27, 2008 at 4:33 PM, Antonis Christofides
<ant...@itia.ntua.gr> wrote:
> There are essentially two things that you can do with a block:
> (1) define it (or redefine it); and (2) insert it somewhere in a
> template. The block tag thus performs different functions depending
> on circumstances:
> * If a block tag with the same name exists in an inherited
> template, then the block tag merely (re)defines the block.
> * If no block tag with the same name is inherited, then the block tag
> at the same time defines the block AND inserts it in the template.

class A(object):
def meth(self):
return "A"

class B(A):
def meth(self):
return "B"

--------------------------------------------------

(a.html)
{% block bl %}A{% endblock %}

(b.html)
{% extends "a.html" %}
{% block bl %}B{% endblock %}

Can you see the similarity? It's a hierarchy. A base.html with a block
"content" without content or a placeholder is just like an abstract
class.

HTH,
Ludvig

Reply all
Reply to author
Forward
0 new messages