Opened 17 years ago
Last modified 7 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 | 
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)
Change History (11)
comment:1 by , 17 years ago
comment:2 by , 17 years ago
| Triage Stage: | Unreviewed → Design decision needed | 
|---|
comment:3 by , 14 years ago
| Severity: | → Normal | 
|---|---|
| Type: | → New feature | 
comment:4 by , 14 years ago
| Easy pickings: | unset | 
|---|---|
| Has patch: | set | 
| Version: | 1.0 → 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:6 by , 13 years ago
| Cc: | added | 
|---|
comment:7 by , 13 years ago
| Triage Stage: | Design decision needed → 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 by , 12 years ago
| Cc: | 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 , 11 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 , 7 years ago
| Patch needs improvement: | set | 
|---|
typo: second "firstcol" should be "secondcol", like this:
child.html {% extends 'parent.html' %} {% block firstcol %} 1 {% endblock %} {% block secondcol %} 2 {% endblock %}