/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ pub mod account; pub mod admin; pub mod error; pub mod filter_sort; pub mod format; pub mod home; pub mod items; pub mod locale; pub mod node_card; pub mod node_page; pub mod props; pub mod scaffold; pub mod search; pub mod stats; use jellycommon::user::Theme; use markup::DynRender; use scaffold::{RenderInfo, Scaffold}; use serde::{Deserialize, Serialize}; use std::{ path::PathBuf, sync::{LazyLock, Mutex}, }; pub type FlashM = Option<(String, String)>; #[rustfmt::skip] #[derive(Debug, Deserialize, Serialize, Default)] pub struct Config { brand: String, slogan: String, asset_path: PathBuf, } static CONF: LazyLock = LazyLock::new(|| { CONF_PRELOAD .lock() .unwrap() .take() .expect("cache config not preloaded. logic error") }); pub static CONF_PRELOAD: Mutex> = Mutex::new(None); pub fn get_brand() -> String { CONF.brand.clone() } pub fn get_slogan() -> String { CONF.slogan.clone() } /// render as supertrait would be possible but is not /// dyn compatible and I really dont want to expose generics /// that generate rendering code because of compile speed. pub trait Page { fn title(&self) -> String; fn to_render(&self) -> DynRender<'_>; fn class(&self) -> Option<&'static str> { None } } pub fn render_page(page: &dyn Page, renderinfo: RenderInfo) -> String { Scaffold { lang: renderinfo.lang, class: &format!( "{} theme-{}", page.class().unwrap_or("custom-page"), renderinfo .session .as_ref() .map(|s| s.user.theme) .unwrap_or(Theme::Dark) .to_str() ), renderinfo, title: page.title(), main: page.to_render(), } .to_string() } pub struct CustomPage { pub title: String, pub body: String, } impl Page for CustomPage { fn title(&self) -> String { self.title.clone() } fn to_render(&self) -> DynRender<'_> { markup::new!(@markup::raw(&self.body)) } }