#html #template #no-std

no-std nate

Not a Template Engine. Derive Display using a template.

8 releases

0.1.8 Jan 5, 2022
0.1.7 Jan 5, 2022
0.1.5 Dec 19, 2021
0.1.4 Aug 6, 2021
0.1.1 Jul 30, 2021

#25 in Template engine

Download history 5/week @ 2021-09-26 10/week @ 2021-10-10 1/week @ 2021-10-31 5/week @ 2021-11-07 2/week @ 2021-11-21 5/week @ 2021-11-28 6/week @ 2021-12-05 17/week @ 2021-12-19 5/week @ 2021-12-26 43/week @ 2022-01-02 15/week @ 2022-01-09

80 downloads per month

ISC OR MIT OR Apache-2.0

20KB
236 lines

GitHub Workflow Status Crates.io License

Not a Template Engine

This is not a template engine, but sugar to implicitly call write!(…) like in PHP. The only difference is that the output gets XML escaped automatically unless opted-out explicitly.

E.g.

  • templates/greeting.html:

    <h1>Hello, {{user}}!</h1>
    

    The path is relative to the cargo manifest dir (where you find Cargo.toml) of the project.

  • src/main.rs:

    use nate::Nate;
    
    #[derive(Nate)]
    #[template(path = "templates/greeting.html")]
    struct Greetings<'a> {
        user: &'a str,
    }
    
    fn main() {
        let mut output = String::new();
        let tmpl = Greetings { user: "<World>" };
        write!(output, "{}", tmpl).unwrap();
        println!("{}", output);
    }
    
  • Output:

    <h1>Hello, &#60;World&#62;!</h1>
    

No new traits are introduced, instead using #[derive(Nate)] works by implementing fmt::Display. This also makes nesting of NaTE templates possible.

A more complex example would be:

  • src/main.rs:

    use nate::Nate;
    
    #[derive(Nate)]
    #[template(path = "templates/99-bottles.html")]
    struct Template {
        limit: usize,
    }
    
    #[test]
    fn ninetynine_bottles_of_beer() {
        print!("{}", Template { limit: 99 });
    }
    
  • templates/99-bottles.txt:

    {%-
        for i in (1..=self.limit).rev() {
            if i == 1 {
    -%}
    1 bottle of beer on the wall.
    1 bottle of beer.
    Take one down, pass it around.
    {%-
            } else {
    -%}
    {{i}} bottles of beer on the wall.
    {{i}} bottles of beer.
    Take one down, pass it around.
    
    {%
            }
        }
    -%}
    

Inside of a {% code block %} you can write any and all rust code.

Values in {{ value blocks }} are printed XML escaped.

Values in {{{ raw blocks }}} are printed verbatim.

For values in {{{{ debug blocks }}}} their debug message is printed as in "{:?}".

For values in {{{{{ verbose blocks }}}}} their debug message is printed verbose as in "{:#?}".

With {< include >} block you can include a template file. It then behaves like it was copy-pasted into the current file. If the path starts with "." or "..", the file is searched relative to the current file. Otherwise it is search in the project root.

Using hyphens - at the start/end of a block, whitespaces before/after the block are trimmed.

Data blocks {{}} to {{{{{}}}}} and includes {<>} must not be empty. Code {%%} and comment {##} blocks may be empty.

Blocks don't need to be closed at the end of the file.

To debug any errors you can add an argument as in #[template(output = "some/path/generated.rs")]. The generated code is stored in there even if there were parsing errors in the Rust code. The path is relative to the project root (where your Cargo.toml lives).

Dependencies

~1.1–1.6MB
~35K SLoC