Opened 16 years ago

Last modified 6 years ago

#9173 new New feature

Conditional content of template blocks

Reported by: while0pass Owned by: nobody
Component: Template system Version: dev
Severity: Normal Keywords:
Cc: masterjakul@…, FunkyBob Triage Stage: Someday/Maybe
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no
Pull Requests:How to create a pull request

Description

It will be very good if there is some possibility to mark sort of "conditional content" of the template blocks ({% block .. %}), that is the content that is displayed only if in a child template the block has some content. For instance, we have 2 templates:

parent.html

<table>
  <tr>
     <td>{% block firstcol %}{% endblock %}</td>
     <td>{% block secondcol %}{% endblock %}</td>
     {% block thirdcol %}<td>{% blockcontent %}</td>{% endblock %}
  </tr>
</table>
child.html

{% extends 'parent.html' %}

{% block firstcol %} 1 {% endblock %}
{% block firstcol %} 2 {% endblock %}

We should have such an output text:

<table>
  <tr>
     <td> 1 </td>
     <td> 2 </td>
  </tr>
</table>

but not the following:

<table>
  <tr>
     <td> 1 </td>
     <td> 2 </td>
     <td></td>
  </tr>
</table>

According to the ticket's flags, the next step(s) to move this issue forward are:

  • Unknown. The Someday/Maybe triage stage is used to keep track of high-level ideas or long term feature requests.

    It could be an issue that's blocked until a future version of Django (if so, Keywords will contain that version number). It could also be an enhancement request that we might consider adding someday to the framework if an excellent patch is submitted.

    If you're interested in contributing to the issue, raising your ideas on the Django Forum would be a great place to start.

Change History (11)

comment:1 by while0pass, 16 years ago

typo: second "firstcol" should be "secondcol", like this:

child.html

{% extends 'parent.html' %}

{% block firstcol %} 1 {% endblock %}
{% block secondcol %} 2 {% endblock %}

comment:2 by Jacob, 16 years ago

Triage Stage: UnreviewedDesign decision needed

comment:3 by Luke Plant, 14 years ago

Severity: Normal
Type: New feature

by Andy Durdin, 14 years ago

Attachment: ticket9173.diff added

Patch against current trunk

comment:4 by Andy Durdin, 14 years ago

Easy pickings: unset
Has patch: set
Version: 1.0SVN

This scratches an itch for me too, so I thought I’d implement it.

My patch in ticket9173.diff (against r16253) implements a new tag, ifnotempty, with the following behaviour:

    Renders only if at least one variable or template tag within also renders.

    This allows a variable or template tag to be surrounded by markup, with
    the markup omitted if the variable or template tag does not render.

    An `{% else %}` block may also be used.

    In the following example, the section will not be rendered unless another
    template extends this one and overrides the `more_information` block::

        {% ifnotempty %}
            <section>
                <h1>More information</h1>
                {% block more_information %}{% endblock %}
            </section>
        {% endifnotempty %}

comment:5 by Aymeric Augustin, 13 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:6 by masterjakul@…, 13 years ago

Cc: masterjakul@… added

comment:7 by Jacob, 12 years ago

Triage Stage: Design decision neededSomeday/Maybe

I'm wholly unconvinced by the syntax proposed so far; it seems quite complicated and non-intuitive. However, I'm not opposed to the idea in general. So marking "someday" -- if someone comes up with syntax that makes sense and is easy to explain, then we might consider this.

comment:8 by FunkyBob, 11 years ago

Cc: FunkyBob added

I ended up implementing a {% wrapif %} tag, which will render the [optional] head and tail blocks if the body renders as a non-blank [not all whitespace] string.

{% wrapif %}
<td>
{% body %}
{% block whatever %}{% endblock %}
{% tail %}
</td>
{% endwrapif %}

If body is omitted, the first block is assumed to be the body, and the head empty.
If tail is omitted, it is considered empty.

I mostly did this to help move container tags out of for loops, where they'd be inside a {% if forloop.first %} and thus cause a test every iteration.

comment:9 by Markus Amalthea Magnuson, 10 years ago

I was thinking about this the other day. How about something like:

parent.html

<table>
  <tr>
    <td>{% block firstcol %}{% endblock %}</td>
    <td>{% block secondcol %}{% endblock %}</td>
    {% block thirdcol if block.child %}<td>{{ block.child }}</td>{% endblock %}
  </tr>
</table>

Which would introduce a {{ block.child }} thing similar to {{ block.super }}

And also conditional blocks in general, in which you can specify:

{% block title if post.title %}My title{% endif%}

Which is the equivalent of, but shorter than:

{% block title %}
  {% if post.title %}
    {{ post.title }}
  {% else %}
    {{ block.super }}
  {% endif %}
{% endblock %}

What do you think of all the above?

comment:10 by Collin Anderson, 6 years ago

Patch needs improvement: set
Note: See TracTickets for help on using tickets.
Back to Top