Crate ructe [−] [src]
Rust Compiled Templates is a HTML template system for Rust.
Ructe works by converting your templates (and static files) to rust source code, which is then compiled with your project. This has the benefits that:
- Many syntactical and logical errors in templates are caught compile-time, rather than in a running server.
- No extra latency on the first request, since the template are compiled before starting the program.
- The template files does not have to be distributed / installed. Templates are included in the compiled program, which can be a single binary.
The template syntax, which is inspired by Twirl, the Scala-based template engine in Play framework, is documented in the Template syntax module. A sample template may look like this:
@use ::Group;
@use templates::page_base;
@(title: &str, user: Option<String>, groups: &[Group])
@:page_base(title, &user, {
<div class="group">
@if groups.is_empty() {
<p>No pictures.</p>
}
@for g in groups {
<div class="item"><h2>@g.title</h2>
<p><a href="@g.url"><img src="/img/@g.photo.id-s.jpg"></a></p>
<p>@g.count pictures</p>
</div>
}
</div>
})
How to use ructe
Ructe compiles your templates to rust code that should be compiled with your other rust code, so it needs to be called before compiling. Assuming you use cargo, it can be done like this:
First, specify a build script and ructe as a build dependency in
Cargo.toml
:
build = "src/build.rs"
[build-dependencies]
ructe = "^0.2"
Then, in the build script, compile all templates found in the templates directory and put the output where cargo tells it to:
extern crate ructe; use ructe::compile_templates; use std::env; use std::path::PathBuf; fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let in_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()) .join("templates"); compile_templates(&in_dir, &out_dir).expect("compile templates"); }
And finally, include and use the generated code in your code.
The file templates.rs
will contain mod templates { ... }
,
so I just include it in my main.rs
:
include!(concat!(env!("OUT_DIR"), "/templates.rs"));
When calling a template, the arguments declared in the template will be
prepended by a Write
argument to write the output to.
It can be a Vec<u8>
as a buffer or for testing, or an actual output
destination.
The return value of a template is std::io::Result<()>
, which should be
Ok(())
unless writing to the destination fails.
#[test] fn test_hello() { let mut buf = Vec::new(); templates::hello(&mut buf, "World").unwrap(); assert_eq!(buf, b"<h1>Hello World!</h1>\n"); }
Modules
Template_syntax |
This module describes the template syntax used by ructe. |
templates |
The module containing your generated template code will also contain everything from here. |
Functions
compile_static_files |
Create a |
compile_templates |
Create a |