djc / askama

Type-safe, compiled Jinja-like templates for Rust
Apache License 2.0
3.5k stars 221 forks source link

rendering nested block broken by if-else-endif in outer block #1075

Open clonejo opened 4 months ago

clonejo commented 4 months ago

Description

When rendering a nested block as a fragment, an if-else-endif clause in the outer block causes this error message:

error: dedent() called while indentation == 0
  --> testing/tests/block_fragments.rs:35:10
   |
35 | #[derive(Template)]
   |          ^^^^^^^^
   |
   = note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `askama_testing` (test "block_fragments") due to 1 previous error

It does not occur when the same template is rendered as a whole. It does not occur if only a if-endif clause is used.

Environment

askama main from Git (382b5f6a4e3e50676283957ed38d8f719ad6b5df)

How to reproduce

I created a small patch to the test suite: https://github.com/clonejo/askama/commit/96e0fb0e622dfc7be87965b3952677a797032010

testing/templates/fragment-nested-block.html:

{% extends "fragment-base.html" %}

{% block body %}
<p>Don't render me!</p>
{% if true %}
true
{% else %}
false
{% endif %}
{% block nested %}
<p>I should be here.</p>
{% endblock %}
{% endblock %}

{% block other_body %}
<p>Don't render me!</p>
{% endblock %}
djc commented 4 months ago

Can you check if #1054 fixes this problem for you?

clonejo commented 4 months ago

@djc i tried my test suite patch on top of e44b0ca78d773e2c50cb2e5e7807a212f2633752 (from #1054), and i still get the exact same error message.

clonejo commented 4 months ago

Looks like this also triggers the same bug with just if-endif twice in the same row:

{% extends "fragment-base.html" %}

{% block body %}
<p>Don't render me!</p>
{%- if true -%}
true
{%- endif -%}{%- if false -%}
false
{%- endif -%}
{% block nested %}
<p>I should be here.</p>
{% endblock %}
{% endblock %}

{% block other_body %}
<p>Don't render me!</p>
{% endblock %}
djc commented 4 months ago

Would you mind submitting a PR adding this as an integration test? I plan to carve out some time to work on this soon.

clonejo commented 3 months ago

Somehow i could not reproduce the bug with endif-if on the same row on current master (5a83872), and even not on 382b5f6.

The reproducer for the original issue is up at #1080.

djc commented 3 months ago

Thanks for all your efforts, will try to look into this issue soon!

(Currently on vacation so might take me a few weeks.)

clonejo commented 3 months ago

Enjoy your vacation, open source can wait :)

clonejo commented 3 months ago

I have been digging at the code a bit. What may contribute here is that in some cases, Buffer::writeln() handles indent/dedent, and sometimes the code calling writeln does. I think the code would be easier to reason about if it was only one of the two.