Krolyxon
Commit ec28036

ferreniumsrchandlersmod.rs

80 lines · 2.4 KB · Rust

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