Rocket Hello World with Tera Templates

Rocket web Tera rocket_dyn_templates Template context! render attach fairing

Part of the series about the Rocket web framework.

Rocket is integrated with two templating systems. In this article we'll see how to use the Tera templating system.

Directory layout

$ tree
.
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── main.rs
│   └── tests.rs
└── templates
    └── index.html.tera

Dependencies

For this to work, we'll need the rocket_dyn_templates crate with the tera feature.

This is how Cargo.toml looks like:

examples/rocket/hello-world-tera-template/Cargo.toml

[package]
name = "hello-world-tera-template"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rocket = "0.5"
rocket_dyn_templates = { version = "0.1", features = ["tera"] }

Template

The template itself has to be placed in the templates folder of our crate and it needs to have the .html.tera extension. In this example we use some minimal HTML and a single template variable that we want to substitute. We need that double curly braces around it.

examples/rocket/hello-world-tera-template/templates/index.html.tera

Hello <b>{{ name }}!</b>

The code

examples/rocket/hello-world-tera-template/src/main.rs

#[macro_use]
extern crate rocket;

use rocket_dyn_templates::{context, Template};

#[get("/")]
fn index() -> Template {
    Template::render("index", context! {
        name: "Rocket with Tera"
    })
}

#[launch]
fn rocket() -> _ {
    rocket::build()
        .mount("/", routes![index])
        .attach(Template::fairing())
}

#[cfg(test)]
mod tests;

So what are the interesting parts here?

We need to import both the Template and the context:

use rocket_dyn_templates::{context, Template};

Our route is expected to return a Template so we have:

fn index() -> Template {

In the route itself we can pass values for the placeholders of the template using the context! macro and we call the render method.

Template::render("index", context! {
    name: "Rocket with Tera"
})

Finally, we had to attach the Template::fairing.

.attach(Template::fairing())

I admit, I haven't heard this word before and I don't really know what it means, but without that Rocket complained:

Error: returning `Template` responder without attaching `Template::fairing()`.
   >> To use or query templates, you must attach `Template::fairing()`.
   >> See the `Template` documentation for more information.

Testing

There is nothing new in the test compared to the previous cases. We only changed the expected text. We still verify that the Content-Type is text/html.

examples/rocket/hello-world-tera-template/src/tests.rs

use rocket::http::Status;
use rocket::local::blocking::Client;

#[test]
fn hello_world() {
    let client = Client::tracked(super::rocket()).unwrap();
    let response = client.get("/").dispatch();

    assert_eq!(response.status(), Status::Ok);
    assert_eq!(
        response.headers().get_one("Content-Type").unwrap(),
        "text/html; charset=utf-8"
    );
    assert_eq!(response.into_string(), Some("Hello <b>Rocket with Tera!</b>".into()));
}

cargo test

Running

cargo run

Related Pages

Rocket - web development with Rust

Author

Gabor Szabo (szabgab)

Gabor Szabo, the author of the Rust Maven web site maintains several Open source projects in Rust and while he still feels he has tons of new things to learn about Rust he already offers training courses in Rust and still teaches Python, Perl, git, GitHub, GitLab, CI, and testing.

Gabor Szabo