djc / askama

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

0.12.1 only allow lower-case variable name in template #924

Closed jan24 closed 9 months ago

jan24 commented 11 months ago

I don't know if I asked a stupid question, but I spend one day to find it ! my rust version is 1.74.0, I run it on my win11 and WSL ubuntu 22.04, see the same error below

use askama::Template;

#[derive(Template)] 
#[template(path = "hello.html")]
struct HelloTemplate<'a> {
    nAme: &'a str, 
}
fn main() {
    let hello = HelloTemplate { nAme: "world" }; 
    println!("{}", hello.render().unwrap());
}
Hello, {{ nAme }}!
[package]
name = "hello"
version = "0.1.0"
edition = "2021"

[dependencies]
askama="0.12.1"
[xxx.DESKTOP-ABCDE12] ⮞ cargo run -p hello Compiling hello v0.1.0 (C:\xx\xx\xx\hello) error[E0425]: cannot find value nAme in this scope --> hello\src\main.rs:3:10 3 #[derive(Template)] ^^^^^^^^

= note: this error originates in the derive macro Template (in Nightly builds, run with -Z macro-backtrace for more info) help: you might have meant to use the available field | 3 | #[derive(self.Template)] | +++++

For more information about this error, try rustc --explain E0425. error: could not compile hello (bin "hello") due to previous error

jan24 commented 11 months ago

I'm new to axum, I have learn the docs https://djc.github.io/askama/askama.html, but it seems not have the request of lower case

djc commented 11 months ago

I suggest you get the macro expansion via Rust Analyzer or via the debugging features. I guess the code generator applies some heuristics that take variable name casing into account in a way that might be surprising.

jan24 commented 11 months ago

I just find that, the var name with upper case => Path(["nAme"]), the var name with lower case => Var("na")) Var("me")), but I don't know it is the purpose of Askama or not ? I don't find the code which product this difference either.

<h1>Hello, {{ na }} {{ nAme }} {{ me }} !</h1>
use askama::Template;

#[derive(Template)]
#[template(path = "hello.html", print = "all")]
struct HelloTemplate<'a> {
    na: &'a str,
    nAme: &'a str,
    me: &'a str,
}

fn main() { println!("hello world"); }
[aaaa.DESKTOP-ABCDE] ⮞ cargo run -p hello
   Compiling hello v0.1.0 (C:\aaa\aaa\aaa\hello)
[Lit(Lit { lws: "", val: "<h1>Hello,", rws: " " }), Expr(Ws(None, None), Var("na")), Lit(Lit { lws: " ", val: "", rws: "" }), Expr(Ws(None, None), Path(["nAme"])), Lit(Lit { lws: " ", val: "", rws: "" }), Expr(Ws(None, None), Var("me")), Lit(Lit { lws: " ", val: "!</h1>", rws: "" })]
......
error[E0425]: cannot find value `nAme` in this scope
 --> hello\src\main.rs:3:10
  |
3 | #[derive(Template)]
  |          ^^^^^^^^
  |
  = note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might have meant to use the available field
  |
3 | #[derive(self.Template)]
  |          +++++

For more information about this error, try `rustc --explain E0425`.
error: could not compile `hello` (bin "hello") due to previous error
MagnusWestin commented 10 months ago

I ran in to the same issue. For some reason if you have uppercase, the code it generates fails. See this example

            expr0 = &::askama::MarkupDisplay::new_unsafe(&(self.title), ::askama::Html),
            expr1 = &::askama::MarkupDisplay::new_unsafe(&(xxxYYY), ::askama::Html),

with uppercase, it doesnt add self. in front of the variable name. I couldn't not find any mention in the documentation for this. It's kind of an annoying limitation if intended.

if I make YYY to lower case, it generates the following

            expr0 = &::askama::MarkupDisplay::new_unsafe(&(self.title), ::askama::Html),
            expr1 = &::askama::MarkupDisplay::new_unsafe(&(self.xxxyyy), ::askama::Html),

You can get around it by just doing this in the html template

<h1>{{ self.xxxYYY }}</h1>

any reason for this behavior?

djc commented 9 months ago

Proposed a fix in #951.