Opened 7 years ago

Last modified 6 months ago

#9173 new New feature

Conditional content of template blocks

Reported by: while0pass Owned by: nobody
Component: Template system Version: master
Severity: Normal Keywords:
Cc: masterjakul@…, FunkyBob Triage Stage: Someday/Maybe
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

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>

Attachments (1)

ticket9173.diff (5.8 KB) - added by adurdin 4 years ago.
Patch against current trunk

Download all attachments as: .zip

Change History (10)

comment:1 Changed 7 years ago by while0pass

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

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

child.html

{% extends 'parent.html' %}

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

comment:2 Changed 6 years ago by jacob

  • Triage Stage changed from Unreviewed to Design decision needed

comment:3 Changed 4 years ago by lukeplant

  • Severity set to Normal
  • Type set to New feature

Changed 4 years ago by adurdin

Patch against current trunk

comment:4 Changed 4 years ago by adurdin

  • Easy pickings unset
  • Has patch set
  • Version changed from 1.0 to SVN

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 Changed 3 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:6 Changed 3 years ago by masterjakul@…

  • Cc masterjakul@… added

comment:7 Changed 2 years ago by jacob

  • Triage Stage changed from Design decision needed to Someday/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 Changed 22 months ago by FunkyBob

  • 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 Changed 6 months ago by alimony

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?

Note: See TracTickets for help on using tickets.
Back to Top