qrush_engine/services/
template_service.rs

1use actix_web::HttpResponse;
2use once_cell::sync::Lazy;
3use std::sync::Arc;
4use tera::{Context, Tera};
5
6// Centralized template list to keep code clean and DRY
7const TEMPLATE_FILES: &[(&str, &str)] = &[
8    ("layout.html.tera", include_str!("../templates/layout.html.tera")),
9    ("dead_jobs.html.tera", include_str!("../templates/dead_jobs.html.tera")),
10    ("metrics.html.tera", include_str!("../templates/metrics.html.tera")),
11    ("queue_metrics.html.tera", include_str!("../templates/queue_metrics.html.tera")),
12    ("delayed_jobs.html.tera", include_str!("../templates/delayed_jobs.html.tera")),
13    ("summary.html.tera", include_str!("../templates/summary.html.tera")),
14    ("cron_jobs.html.tera", include_str!("../templates/cron_jobs.html.tera")),
15    ("failed_jobs.html.tera", include_str!("../templates/failed_jobs.html.tera")),
16    ("retry_jobs.html.tera", include_str!("../templates/retry_jobs.html.tera")),
17    ("errors/404.html.tera", include_str!("../templates/errors/404.html.tera")),
18    ("errors/500.html.tera", include_str!("../templates/errors/500.html.tera")),
19];
20
21static TEMPLATES: Lazy<Arc<Tera>> = Lazy::new(|| {
22    let mut tera = Tera::default();
23
24    for (name, content) in TEMPLATE_FILES {
25        tera.add_raw_template(name, content)
26            .unwrap_or_else(|e| panic!("Failed to add {}: {}", name, e));
27    }
28
29    tera.autoescape_on(vec![]); // Disable autoescaping if rendering raw HTML
30    Arc::new(tera)
31});
32
33pub async fn render_template(template_name: &str, ctx: Context) -> HttpResponse {
34    let tera = Arc::clone(&TEMPLATES);
35    match tera.render(template_name, &ctx) {
36        Ok(html) => HttpResponse::Ok().content_type("text/html").body(html),
37        Err(err) => {
38            eprintln!("Template render error: {:?}", err);
39            let mut ctx = Context::new();
40            ctx.insert("error", &err.to_string());
41            let fallback_html = tera
42                .render("errors/500.html.tera", &ctx)
43                .unwrap_or_else(|_| "Internal Server Error".to_string());
44            HttpResponse::InternalServerError().body(fallback_html)
45        }
46    }
47}
48
49// Optional helper for 404 rendering
50pub async fn render_404() -> HttpResponse {
51    let tera = Arc::clone(&TEMPLATES);
52    let ctx = Context::new();
53    let html = tera
54        .render("errors/404.html.tera", &ctx)
55        .unwrap_or_else(|_| "Page Not Found".to_string());
56    HttpResponse::NotFound().body(html)
57}