generated from alecodes/base-template
feat: add minijinja as template engine
This commit is contained in:
parent
5a9b871e42
commit
6cb75aa442
10 changed files with 150 additions and 31 deletions
|
|
@ -1,5 +1,8 @@
|
|||
use axum::response::Html;
|
||||
use axum::{http::StatusCode, response::IntoResponse};
|
||||
use axum::{
|
||||
http::StatusCode,
|
||||
response::{Html, IntoResponse},
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
|
|
@ -34,6 +37,8 @@ impl IntoResponse for Error {
|
|||
),
|
||||
};
|
||||
|
||||
debug!(error = ?self);
|
||||
|
||||
(status, message).into_response()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
25
src/lib.rs
25
src/lib.rs
|
|
@ -1,3 +1,28 @@
|
|||
mod error;
|
||||
pub mod router;
|
||||
|
||||
pub use error::{Error, Result, ResultTemplate};
|
||||
use minijinja::{Environment, Template};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Link {
|
||||
pub path: String,
|
||||
pub text: String,
|
||||
pub subpages: Vec<Self>,
|
||||
}
|
||||
|
||||
pub struct AppState {
|
||||
tmpl_env: Environment<'static>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
pub fn new(tmpl_env: Environment<'static>) -> Arc<Self> {
|
||||
Arc::new(AppState { tmpl_env })
|
||||
}
|
||||
|
||||
pub fn get_template(&self, name: &str) -> Result<Template> {
|
||||
Ok(self.tmpl_env.get_template(name)?)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
48
src/main.rs
48
src/main.rs
|
|
@ -1,21 +1,31 @@
|
|||
#![allow(unused)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use compendium::{router, AppState, Link, Result};
|
||||
use minijinja::{Environment, Value};
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::extract::State;
|
||||
use axum::http::StatusCode;
|
||||
use axum::response::Html;
|
||||
use axum::routing::get;
|
||||
use axum::Router;
|
||||
use compendium::{Result, ResultTemplate};
|
||||
use minijinja::{context, Environment};
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::info;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
struct AppState {
|
||||
tmpl_env: Environment<'static>,
|
||||
fn load_templates() -> Result<Environment<'static>> {
|
||||
let mut tmpl_env = Environment::new();
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
tmpl_env.set_loader(minijinja::path_loader("templates")); // Path is relative to project root
|
||||
|
||||
// only enable in production build
|
||||
#[cfg(not(debug_assertions))]
|
||||
minijinja_embed::load_templates!(&mut env);
|
||||
|
||||
let global_routes = vec![Link {
|
||||
path: "/about".to_owned(),
|
||||
text: "About".to_owned(),
|
||||
subpages: vec![],
|
||||
}];
|
||||
tmpl_env.add_global("global_routes", Value::from_serialize(&global_routes));
|
||||
|
||||
Ok(tmpl_env)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
@ -30,15 +40,11 @@ async fn main() -> Result<()> {
|
|||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
|
||||
let mut tmpl_env = Environment::new();
|
||||
tmpl_env.add_template("base", include_str!("../templates/base.html"))?;
|
||||
let mut tmpl_env = load_templates()?;
|
||||
|
||||
let app_state = Arc::new(AppState { tmpl_env });
|
||||
|
||||
let app = Router::new()
|
||||
.route("/", get(handler_home))
|
||||
let app = router::new()
|
||||
.layer(TraceLayer::new_for_http().on_request(()))
|
||||
.with_state(app_state);
|
||||
.with_state(AppState::new(tmpl_env));
|
||||
|
||||
// Add hot reload only on dev mode
|
||||
#[cfg(debug_assertions)]
|
||||
|
|
@ -50,11 +56,3 @@ async fn main() -> Result<()> {
|
|||
axum::serve(listener, app).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handler_home(State(state): State<Arc<AppState>>) -> ResultTemplate {
|
||||
let template = state.tmpl_env.get_template("base")?;
|
||||
|
||||
let content = template.render(context!())?;
|
||||
|
||||
Ok(Html(content))
|
||||
}
|
||||
|
|
|
|||
17
src/router.rs
Normal file
17
src/router.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
use axum::{extract::State, response::Html, routing::get, Router};
|
||||
use minijinja::context;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{AppState, ResultTemplate};
|
||||
|
||||
pub fn new() -> Router<Arc<AppState>> {
|
||||
Router::new().route("/", get(handler_home))
|
||||
}
|
||||
|
||||
async fn handler_home(State(state): State<Arc<AppState>>) -> ResultTemplate {
|
||||
let template = state.tmpl_env.get_template("base.html")?;
|
||||
|
||||
let content = template.render(context!())?;
|
||||
|
||||
Ok(Html(content))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue