aboutsummaryrefslogtreecommitdiffstats
path: root/src/theming/hbs.rs
blob: 398715ada7b4a36a0c0c5be0cd2071a9bc275c51 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// SPDX-License-Identifier: AGPL-3.0-only
use std::sync::LazyLock;

use handlebars::*;
use reqwest::StatusCode;

use crate::CONFIG;

static INTERNAL_THEMES: &[(&str, &str)] = &[("plain", include_str!("hbs/plain.hbs"))];

static HANDLEBARS: LazyLock<Handlebars> = LazyLock::new(|| {
  let mut hb = Handlebars::new();
  handlebars_helper!(url_encode: |s: String| urlencoding::encode(&s));

  hb.register_helper("url-encode", Box::new(url_encode));

  for (key, fulltext) in INTERNAL_THEMES {
    log::info!("Registering internal handlebars theme `{key}`");
    hb.register_template_string(key, fulltext).unwrap();
  }
  hb.set_dev_mode(CONFIG.theme_dev);

  if let Some(themes_dir) = CONFIG.theme_dir.as_ref() {
    log::info!("Registering handlebars theme dir `{themes_dir}` with extension `{}`.", CONFIG.theme_ext_hbs);
    hb.register_templates_directory(&CONFIG.theme_ext_hbs, themes_dir.as_ref()).unwrap();
  }

  hb
});

pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String, StatusCode>> {
  let templ = HANDLEBARS.get_template(name)?;
  let ctx = Context::wraps(ctx).unwrap();
  let render = templ.renders(&HANDLEBARS, &ctx, &mut RenderContext::new(Some(&name.into()))).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR);
  Some(render)
}

pub fn touch() {
  LazyLock::force(&HANDLEBARS);
}