askama icon indicating copy to clipboard operation
askama copied to clipboard

Request: Content check blocks

Open jaw-sh opened this issue 2 years ago • 3 comments

Some templating engines support a streamlined "if content" block.

For instance, in XenForo's templating engine, it looks like this. image

Take for instance the following scenario which is very common in a template.

<ul class="moderator-actions">
    ​{% if client.can_update_post(post) %}<li><a href="/posts/{{ post.id }}/edit">Edit</a></li>{% endif %}
    ​{% if client.can_delete_post(post) %}<li><a href="/posts/{{ post.id }}/delete">Delete</a></li>{% endif %}
</ul>

We can have many buttons in this list which should only display to the client if they have the ability to use them. The more buttons in this list, the more checks we are using. However, the list itself should only render at all if at least a single item in the list is available.

To achieve this effect, we'd need to add a check like this:

{% if client.can_update_post(post) || if client.can_delete_post(post)  %}
<ul class="moderator-actions">
    ​{% if client.can_update_post(post) %}<li><a href="/posts/{{ post.id }}/edit">Edit</a></li>{% endif %}
    ​{% if client.can_delete_post(post) %}<li><a href="/posts/{{ post.id }}/delete">Delete</a></li>{% endif %}
</ul>
{% endif %}

This is undesirable for two reasons. First, if this list had 10 options, we would need 10 checks, and that is very clumsy to write out. Second, these checks add computational complexity, so needing to run them all twice just for a cosmetic effect is a very poor fix.

A content check could look like this.

{% contentcheck  %}
<ul class="moderator-actions">
    {% content %}
    ​{% if client.can_update_post(post) %}<li><a href="/posts/{{ post.id }}/edit">Edit</a></li>{% endif %}
    ​{% if client.can_delete_post(post) %}<li><a href="/posts/{{ post.id }}/delete">Delete</a></li>{% endif %}
    {% endcontent %}
</ul>
{% endcontentcheck %}

If only whitespace exists within a {% content %} block, then the entire {% contentcheck %} will not render.

This should be nestable. Example: A list may have two categories of options with a header. The category+header does not render unless it has at least one option. The whole list will not render unless at least one category is visible.

jaw-sh avatar Jan 14 '22 13:01 jaw-sh

What Rust code would you expect your template example to compile to?

djc avatar Jan 14 '22 13:01 djc

Please have a look if building a tuple as in this test would work for you. To me it feels much more rust-y and jinja-y than a {% contentcheck %} block.

Kijewski avatar Jan 28 '22 10:01 Kijewski

I agree, that's an acceptable solution.

jaw-sh avatar Jan 28 '22 11:01 jaw-sh