Krolyxon
Commit 4e844bb

ferreniumsrchandlersmod.rs

73 lines · 2.3 KB · Rust

1//! Request handlers. Each page is an askama template that embeds a [`Layout`].
2
3pub mod blob;
4pub mod commit;
5pub mod error;
6pub mod index;
7pub mod log;
8pub mod raw;
9pub mod refs;
10pub mod repo;
11pub mod summary;
12pub mod tree;
13
14use std::sync::Arc;
15
16use askama::Template;
17use axum::http::StatusCode;
18use axum::response::{Html, IntoResponse, Response};
19
20use crate::config::Config;
21use crate::server::assets;
22use crate::state::AppState;
23
24/// Data shared by every page: site chrome, asset URLs and customization.
25pub struct Layout {
26 /// `server.base_path`, always ending in `/`.
27 pub base: String,
28 /// `{base}-/static/{hash}/`
29 pub static_base: String,
30 pub site_title: String,
31 /// Full `<title>` text.
32 pub page_title: String,
33 /// Server default theme: `auto`, `dark` or `light`.
34 pub theme: &'static str,
35 /// Versioned URL of `/-/site.css`, when there is anything in it.
36 pub site_css: Option<String>,
37 pub header: Option<Arc<str>>,
38 pub footer: Option<Arc<str>>,
39 pub version: &'static str,
40}
41
42impl Layout {
43 /// `title` is the page-specific part; the site title is appended.
44 pub fn new(state: &AppState, config: &Config, title: Option<&str>) -> Self {
45 let base = config.server.base_path.clone();
46 let site_title = config.site.title.clone();
47 Layout {
48 static_base: format!("{base}-/static/{}/", state.assets.hash()),
49 site_css: assets::site_css_version(config).map(|v| format!("{base}-/site.css?v={v}")),
50 page_title: match title {
51 Some(t) => format!("{t} · {site_title}"),
52 None => site_title.clone(),
53 },
54 site_title,
55 base,
56 theme: config.ui.theme.as_str(),
57 header: config.custom.header.clone(),
58 footer: config.custom.footer.clone(),
59 version: env!("CARGO_PKG_VERSION"),
60 }
61 }
62}
63
64/// Render a template into an HTML response with the given status.
65pub fn render(status: StatusCode, page: &impl Template) -> Response {
66 match page.render() {
67 Ok(html) => (status, Html(html)).into_response(),
68 Err(e) => {
69 tracing::error!("template error: {e}");
70 (StatusCode::INTERNAL_SERVER_ERROR, "internal error\n").into_response()
71 }
72 }
73}