README.md

Cuach, a HTML template system for Rust

Cuach defines a single trait Render , usable to produce HTML pages from templates and Rust struct s. Cuach compiles on stable Rust and uses procedural macros to produce efficient static code.

Cuach requires a folder called templates at the root of a repository (alongside Cargo.toml ). Then, if that folder contains a file called index.html , we can use it like so:

#[macro_use] extern crate cuach; use cuach::*; #[template(path="index.html")] struct A<'a> { field: &'a str, other_field: usize } fn main() { println!("{}, (A { field: "blah", other_field: 0 }).render().unwrap()) }

The template can be as simple as an empty file, or contain more elaborate things, such as:

<html> <body> field is equal to <strong>{ self.field }</strong>, and other_field to { self.other_field }. </body> </html>

Rules

All the variables and functions of the module where A is defined are in scope in the template. There is also an extra variable in scope, w , of type &mut std::fmt::Write . For any Rust expression e , { e } in the template gets translated to (e).render_into(w) .

Moreover, more complex Rust expressions can be used using HTML comments. For instance, the following produces ten HTML paragraphs, with 0, 1, …, 9 as their contents. Anything inside HTML comments is parsed as Rust.

<!-- for i in 0..10 { --> <p>{ i }</p> <!-- } -->

This means in particular that any expression of the form { e } in the template is strictly equivalent to

(e).render_into(w)?;

Whitespace and escaping

Any amount of whitespace between tags or comments is ignored if it contains at least one newline character, and is output as is else. One way to force whitespace on an otherwise blank line is to add whitespace between two HTMLcomments, like so:

<!-- --> <!-- -->

Comments can be used in the templates, but they have to be Rust comments inside HTML comments:

<!-- // this is a comment --> <!-- /* this is another, multiline, comment */ -->

The parsing of templates is done using an XML parsing library, xml-rs. Therefore, standard XML escaping works and can be used, but it sometimes conflicts with Rust borrows. Cuach handles that situation by replacing, before parsing, all & that are not recognised by regular expression &[a-z]+; with & . After parsing, all instances of & are converted back to & .

Including other files