From e7fcd64b3a6582b9792b403dada4f3694c4a5c57 Mon Sep 17 00:00:00 2001 From: Valerio Ageno Date: Sun, 18 Aug 2024 12:25:12 +0200 Subject: [PATCH] feat: add sitemaps to documentation website --- apps/documentation/Cargo.toml | 2 + .../src/components/hero/hero.tsx | 2 +- apps/documentation/src/routes/sitemap.xml.rs | 61 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 apps/documentation/src/routes/sitemap.xml.rs diff --git a/apps/documentation/Cargo.toml b/apps/documentation/Cargo.toml index 3c7f3d4d..00b56059 100644 --- a/apps/documentation/Cargo.toml +++ b/apps/documentation/Cargo.toml @@ -9,5 +9,7 @@ path = ".tuono/main.rs" [dependencies] tuono_lib = "0.10.0" +glob = "0.3.1" +time = { version = "0.3", features = ["macros"] } serde = { version = "1.0.202", features = ["derive"] } diff --git a/apps/documentation/src/components/hero/hero.tsx b/apps/documentation/src/components/hero/hero.tsx index 4aa07282..6ff60759 100644 --- a/apps/documentation/src/components/hero/hero.tsx +++ b/apps/documentation/src/components/hero/hero.tsx @@ -35,7 +35,7 @@ export default function Hero(): JSX.Element { size="lg" style={{ border: 'solid 1px var(--mantine-color-violet-1)' }} color="gray" - leftSection="cargo install tuono" + leftSection="$ cargo install tuono" rightSection={ copied ? ( diff --git a/apps/documentation/src/routes/sitemap.xml.rs b/apps/documentation/src/routes/sitemap.xml.rs new file mode 100644 index 00000000..5fa2f4b4 --- /dev/null +++ b/apps/documentation/src/routes/sitemap.xml.rs @@ -0,0 +1,61 @@ +use tuono_lib::reqwest::{Client, StatusCode}; +use tuono_lib::{Request, Response}; +use tuono_lib::axum::http::{header, HeaderMap}; +use glob::glob; +use time::OffsetDateTime; + +const FILE_TO_EXCLUDE: [&str; 2] = ["sitemap.xml", "__root"]; + +const SITEMAP: &str = r#" + + [PLACEHOLDER] +"#; + +fn load_routes() -> Vec { + let mut paths: Vec = vec![]; + + for entry in glob("./src/routes/**/*").expect("Failed to glob src/routes folder").flatten() { + if !entry.is_dir() { + let path = clean_path(format!("/{}", entry.to_string_lossy())); + + if !FILE_TO_EXCLUDE.iter().any(|exclude| path.ends_with(exclude)) { + paths.push(path) + } + } + } + paths +} + +fn clean_path(value: String) -> String { + value + .replace("src/routes/", "") + .replace(".mdx", "") + .replace(".tsx", "") + .replace(".rs", "") + .replace("index", "") +} + +#[tuono_lib::handler] +async fn generate_sitemap(_req: Request, _fetch: Client) -> Response { + let mut headers = HeaderMap::new(); + headers.insert(header::CONTENT_TYPE, "text/xml".parse().unwrap()); + + let routes = load_routes(); + + let mut sitemaps = String::new(); + + for path in routes { + let mut url = format!("https://tuono.dev{}", path); + + if url.ends_with('/') { + url.pop(); + } + + sitemaps.push_str( + &format!(r#"{}{}"#,url, OffsetDateTime::now_utc().date()) + ) + } + + Response::Custom((StatusCode::OK, headers, SITEMAP.replace("[PLACEHOLDER]", &sitemaps))) +} +