add minijinja templating example (#2523)

This commit is contained in:
Deffendor 2024-02-11 12:17:41 +01:00 committed by GitHub
parent 5b4dc2dafe
commit 6bc400104e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 133 additions and 0 deletions

View file

@ -0,0 +1,10 @@
[package]
name = "example-templates-minijinja"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
axum = { path = "../../axum" }
minijinja = "1.0.11"
tokio = { version = "1.0", features = ["full"] }

View file

@ -0,0 +1,87 @@
//! Run with
//!
//! ```not_rust
//! cargo run -p example-templates-minijinja
//! ```
//! Demo for the MiniJinja templating engine.
//! Exposes three pages all sharing the same layout with a minimal nav menu.
use axum::extract::State;
use axum::http::StatusCode;
use axum::{response::Html, routing::get, Router};
use minijinja::{context, Environment};
use std::sync::Arc;
struct AppState {
env: Environment<'static>,
}
#[tokio::main]
async fn main() {
// init template engine and add templates
let mut env = Environment::new();
env.add_template("layout", include_str!("../templates/layout.jinja"))
.unwrap();
env.add_template("home", include_str!("../templates/home.jinja"))
.unwrap();
env.add_template("content", include_str!("../templates/content.jinja"))
.unwrap();
env.add_template("about", include_str!("../templates/about.jinja"))
.unwrap();
// pass env to handlers via state
let app_state = Arc::new(AppState { env });
// define routes
let app = Router::new()
.route("/", get(handler_home))
.route("/content", get(handler_content))
.route("/about", get(handler_about))
.with_state(app_state);
// run it
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.unwrap();
println!("listening on {}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
}
async fn handler_home(State(state): State<Arc<AppState>>) -> Result<Html<String>, StatusCode> {
let template = state.env.get_template("home").unwrap();
let rendered = template
.render(context! {
title => "Home",
welcome_text => "Hello World!",
})
.unwrap();
Ok(Html(rendered))
}
async fn handler_content(State(state): State<Arc<AppState>>) -> Result<Html<String>, StatusCode> {
let template = state.env.get_template("content").unwrap();
let some_example_entries = vec!["Data 1", "Data 2", "Data 3"];
let rendered = template
.render(context! {
title => "Content",
entries => some_example_entries,
})
.unwrap();
Ok(Html(rendered))
}
async fn handler_about(State(state): State<Arc<AppState>>) -> Result<Html<String>, StatusCode> {
let template = state.env.get_template("about").unwrap();
let rendered = template.render(context!{
title => "About",
about_text => "Simple demonstration layout for an axum project with minijinja as templating engine.",
}).unwrap();
Ok(Html(rendered))
}

View file

@ -0,0 +1,6 @@
{% extends "layout" %}
{% block title %}{{ super() }} | {{ title }} {% endblock %}
{% block body %}
<h1>{{ title }}</h1>
<p>{{ about_text }}</p>
{% endblock %}

View file

@ -0,0 +1,10 @@
{% extends "layout" %}
{% block title %}{{ super() }} | {{ title }} {% endblock %}
{% block body %}
<h1>{{ title }}</h1>
{% for data_entry in entries %}
<ul>
<li>{{ data_entry }}</li>
</ul>
{% endfor %}
{% endblock %}

View file

@ -0,0 +1,6 @@
{% extends "layout" %}
{% block title %}{{ super() }} | {{ title }} {% endblock %}
{% block body %}
<h1>{{ title }}</h1>
<p>{{ welcome_text }}</p>
{% endblock %}

View file

@ -0,0 +1,14 @@
<!doctype html>
<html>
<head><title>{% block title %}Website Name{% endblock %}</title></head>
<body>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/content">Content</a></li>
<li><a href="/about">About</a></li>
</ul>
</nav>
{% block body %}{% endblock %}
</body>
</html>