Templating using askama
Askama implements a type-safe, Jinja-like template engine. While the templating engine itself
is independent of any particular application, the askama_axum
crate provides additional
integration points by converting template results to response objects. Because Askama evaluates
templates at compile time, it is both safe to use and fast to evaluate. On the other hand, it
cannot be fed with templates by users at run-time.
Dependencies
[dependencies]
askama = { git = "https://github.com/djc/askama", features = ["with-axum"] }
askama_axum = { git = "https://github.com/djc/askama" }
axum = "0.5"
tokio = { version = "1", features = ["full"] }
Code
First create a new sibling directory templates
next to the src
directory and add an
index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Askama</title>
</head>
<body>
<p>Hello {{ name }}, you are {{ age }} years old.</p>
</body>
</html>
Note that we refer to the two template variables name
and age
. Thanks to the compile-time
guarantees of askama, the compiler will complain if we do not derive a template that contains these
variables:
use askama::Template;
use axum::extract::Path;
use axum::routing::get;
use axum::Server;
#[derive(Template)]
#[template(path = "index.html")]
struct HtmlTemplate {
name: String,
age: u8,
}
async fn index(Path((name, age)): Path<(String, u8)>) -> HtmlTemplate {
HtmlTemplate { name, age }
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let app = axum::Router::new().route("/:name/:age", get(index));
Server::bind(&"0.0.0.0:8080".parse()?)
.serve(app.into_make_service())
.await?;
Ok(())
}
Run
Start the server with
cargo run --bin templating-with-askama
Now, lets try to get /john/32
:
$ curl -i http://127.0.0.1:8080/john/32
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 167
date: Tue, 08 Mar 2022 20:13:10 GMT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Askama</title>
</head>
<body>
<p>Hello john, you are 32 years old.</p>
</body>
</html>