Krolyxon
Commit 55c1225

ferreniumsrchandlersmod.rs

71 lines · 2.2 KB · Rust

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