repos
/ status-rust master

status-rust

mirror archived upstream

Single-binary self-hosted uptime monitoring and status pages on Rust axum: HTTP probes, Lighthouse audits, SEO crawler, and PDF reports.

axumdockerrustself-hostedsqlitestatus-pageuptime-monitoringvite

2.0 KB · 63 lines · Rust Raw History
 1use axum::{
 2    http::StatusCode,
 3    response::{Html, IntoResponse, Response},
 4};
 5use chrono::Datelike;
 6
 7use crate::templates::{RequestCtx, UserCtx};
 8use crate::AppState;
 9
10/// Render a template to a String, with the standard page context injected.
11///
12/// `extra` is merged on top of the standard context. Templates expect
13/// `user`, `request`, `now`, `BASE_URL`, `messages` to be present; callers
14/// supply page-specific fields like `page` via `extra`.
15///
16/// Returns the rendered body on success, or a 500 Response with the error
17/// already logged.
18pub fn render_to_string(
19    state: &AppState,
20    template: &str,
21    path: &str,
22    authed: bool,
23    extra: minijinja::Value,
24) -> Result<String, Response> {
25    let tmpl = state.env.get_template(template).map_err(|e| {
26        tracing::error!("template '{}': {}", template, e);
27        (StatusCode::INTERNAL_SERVER_ERROR, "template error").into_response()
28    })?;
29    tmpl.render(minijinja::context! {
30        user => UserCtx { is_authenticated: authed },
31        request => RequestCtx {
32            url: String::new(),
33            url_root: "/".to_string(),
34            base_url: state.config.base_url.clone(),
35            path: path.to_string(),
36        },
37        now => minijinja::context! { year => chrono::Local::now().year() },
38        BASE_URL => &state.config.base_url,
39        messages => Vec::<()>::new(),
40        ..extra
41    })
42    .map_err(|e| {
43        tracing::error!("render '{}': {}", template, e);
44        (StatusCode::INTERNAL_SERVER_ERROR, "render error").into_response()
45    })
46}
47
48/// Convenience wrapper around `render_to_string` for HTML responses. Most
49/// page handlers want this; `render_to_string` is for callers that need the
50/// raw body (e.g. markdown downloads, PDF print templates).
51pub fn render(
52    state: &AppState,
53    template: &str,
54    path: &str,
55    authed: bool,
56    extra: minijinja::Value,
57) -> Response {
58    match render_to_string(state, template, path, authed, extra) {
59        Ok(body) => Html(body).into_response(),
60        Err(resp) => resp,
61    }
62}