tera icon indicating copy to clipboard operation
tera copied to clipboard

`super()` can not extend conditional parent blocks

Open vincent-herlemont opened this issue 4 years ago • 8 comments

super() seems can not extend conditional parent blocks.

{# parent #}
{%- if true %}{% block hey %}hello{% endblock hey %}{%- endif -%}

{# child#}
{% extends "parent" %}
{% block hey %}  I say {{ super() }} {% endblock hey %}

If we trie to do it an unrevelent error happens: Tried to use super() in the top level block.

Below tests which can be used to reproduce the error:

#[cfg(test)]
mod tests {
    use tera::Tera;
    use tera::Context;

    #[test]
    fn test_tera_super_block_fail_with_condition() {
        let mut tera = Tera::default();
        tera.add_raw_template("parent", "{%- if true %}{% block hey %}hello{% endblock hey %}{%- endif -%}");
        tera.add_raw_template("child", r#"{% extends "parent" %}
{% block hey %}  I say {{ super() }} {% endblock hey %}
        "#);
        assert!(tera.render("child", &Context::new()).is_err()); // `Tried to use super() in the top level block`
    }

    #[test]
    fn test_tera_super_block_ok_without_condition() {
        let mut tera = Tera::default();
        tera.add_raw_template("parent", "{% block hey %}hello{% endblock hey %}");
        tera.add_raw_template("child", r#"{% extends "parent" %}
{% block hey %}  I say {{ super() }} {% endblock hey %}
        "#);
        assert!(tera.render("child", &Context::new()).is_ok());
    }
}

vincent-herlemont avatar Oct 06 '21 14:10 vincent-herlemont

That's seems happens only if the condition return true.

vincent-herlemont avatar Oct 06 '21 16:10 vincent-herlemont

@Keats any chance you can have a look at this? Because of this bug super() is pretty much unusable IMHO.

Let us know how we can help!

JMLX42 avatar Oct 17 '21 22:10 JMLX42

Tera is currently only looking for blocks at the top level of a template or inside a block, therefore not in a condition. It would be possible to fix but it would mean a big chunk of work. I would recommend putting the condition in the block for now

Keats avatar Oct 18 '21 17:10 Keats

I would recommend putting the condition in the block for now

@Keats thank you for you answer. But that means it is impossible to have conditional blocks and use super().

It would be possible to fix but it would mean a big chunk of work.

Where should we start? :)

JMLX42 avatar Oct 19 '21 11:10 JMLX42

Where should we start? :)

I'll try to have a look tonight to outline the changes required.

Keats avatar Oct 19 '21 11:10 Keats

The issue is that https://github.com/Keats/tera/blob/master/src/template.rs#L53-L73 does not look recursively in other nodes for blocks so when rendering, it tries to look up the block definition and doesn't find it. The code highlighted should look in the whole template instead. It's not ideal and will be done differently in v2 (while parsing)

Keats avatar Oct 20 '21 08:10 Keats

@Keats thanks a million for the details. The thing is that is makes extending templates very tidious:

  • Either all if have to be inside blocks/there cannot be blocks inside if.
  • Or all block content has to be manually/copy/pasted.

That would be immensely helpful if that was fixed/possible in v2. Any timeline for v2?

PS: can we pay for some support/sponsor this feature somehow?

JMLX42 avatar Oct 28 '21 07:10 JMLX42

No timeline for v2 yet, it will depend on what ends up being used for the data layer (maybe https://github.com/tokio-rs/valuable, maybe something else custom so we don't depend on serde_json anymore and avoid copying everything everytime). The parser is 99% written but I keep changing things, this feature will definitely be part of v2 though.

PS: can we pay for some support/sponsor this feature somehow?

You can always sponsor me on GitHub but that's not for a specific feature

Keats avatar Oct 28 '21 19:10 Keats