djc / askama

Type-safe, compiled Jinja-like templates for Rust

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Compilation error when using nested template blocks with in a single template file

Stromdahl opened this issue · comments

Hello! I Encountered a compilation error when using block fragments with Vec<&str> in a single template file. The error does not occur when the template is split into separate files.

This is working like expected

{% block index %}
Section 1: {{ s1 }}
{% endblock %}

{% block section %}
  Value ={{ value }}
{% endblock %}
use askama::Template;

#[derive(Template)]
#[template(path = "combain.txt", block="index")]
struct RenderInPlace<'a> {
   s1: Section<'a>
}

#[derive(Template)]
#[template(path = "combain.txt", block="section")]
struct Section<'a> {
   value: &'a str,
}
fn main() {
    let value = "x";

    let t = RenderInPlace { s1: Section { value } };
    println!("{}", t);
}
Section 1: 


  Value =x

When changing to Vec for the value i get a compilation error..

{% block index %}
Section 1: {{ s1 }}
{% endblock %}

{% block section %}
  {% for value in  values %}
    Value = {{ value }}
  {% endfor %}
{% endblock %}
use askama::Template;

#[derive(Template)]
#[template(path = "combain.txt", block="index")]
struct RenderInPlace<'a> {
   s1: Section<'a>
}

#[derive(Template)]
#[template(path = "combain.txt", block="section")]
struct Section<'a> {
   values: Vec<&'a str>,
}

fn main() {

    let values: Vec<&str>= vec!["a", "b", "c"];

    let t = RenderInPlace { s1: Section { values } };
    println!("{}", t);
}
error[E0609]: no field `value` on type `&Section<'a>`
 --> src/main.rs:9:10
  |
9 | #[derive(Template)]
  |          ^^^^^^^^ unknown field
  |
  = note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)

However when i split the template file in two it is working as expected.
index.html

{% block index %}
Section 1: {{ s1 }}
{% endblock %}

section.html

{% block section %}
  {% for value in  values %}
    Value ={{ value }}
  {% endfor %}
{% endblock %}
use askama::Template;

#[derive(Template)]
#[template(path = "index.txt", block="index")]
struct RenderInPlace<'a> {
   s1: Section<'a>
}

#[derive(Template)]
#[template(path = "section.txt", block="section")]
struct Section<'a> {
   values: Vec<&'a str>,
}

fn main() {

    let values: Vec<&str>= vec!["a", "b", "c"];

    let t = RenderInPlace { s1: Section { values } };
    println!("{}", t);
}
Section 1: 
  
    Value =a
  
    Value =b
  
    Value =c
  

I had the same issue, investigating what's going on.

Ah, it's a bad assumption in the implementation. With my usage, it worked fine, but it still processes all the child nodes of any block, while discarding only writable things. So this means any nodes like the loop tag still gets parsed and generated.

I'm curious to see how you fixed it. The WritableBuffer needs to handle discard too (which I added) and you need to switch this status accordingly. However the handle of whitespace characters becomes tricky. ^^'