mylloon.fr/src/routes/blog.rs
2024-11-09 16:54:38 +01:00

108 lines
2.7 KiB
Rust

use actix_web::{get, http::header::ContentType, routes, web, HttpResponse, Responder};
use cached::proc_macro::once;
use ramhorns::Content;
use crate::{
config::Config,
template::{InfosPage, NavBar},
utils::{
markdown::{File, TypeFileMetadata},
misc::{make_kw, read_file, Html},
routes::blog::{build_rss, get_post, get_posts, Post, BLOG_DIR, MIME_TYPE_RSS, POST_DIR},
},
};
#[get("/blog")]
pub async fn index(config: web::Data<Config>) -> impl Responder {
Html(build_index(config.get_ref().to_owned()))
}
#[derive(Content, Debug)]
struct BlogIndexTemplate {
navbar: NavBar,
about: Option<File>,
posts: Vec<Post>,
no_posts: bool,
}
#[once(time = 60)]
fn build_index(config: Config) -> String {
let blog_dir = format!("{}/{}", config.locations.data_dir, BLOG_DIR);
let mut posts = get_posts(&format!("{blog_dir}/{POST_DIR}"));
// Get about
let about: Option<File> =
read_file(&format!("{blog_dir}/about.md"), &TypeFileMetadata::Generic);
// Sort from newest to oldest
posts.sort_by_cached_key(|p| (p.date.year, p.date.month, p.date.day));
posts.reverse();
config.tmpl.render(
"blog/index.html",
BlogIndexTemplate {
navbar: NavBar {
blog: true,
..NavBar::default()
},
about,
no_posts: posts.is_empty(),
posts,
},
InfosPage {
title: Some("Blog".into()),
desc: Some(format!(
"Liste des posts d'{}",
config.fc.name.unwrap_or_default()
)),
kw: Some(make_kw(&["blog", "blogging"])),
},
)
}
#[derive(Content, Debug)]
struct BlogPostTemplate {
navbar: NavBar,
post: Option<File>,
toc: String,
}
#[get("/blog/p/{id}")]
pub async fn page(path: web::Path<(String,)>, config: web::Data<Config>) -> impl Responder {
Html(build_post(
&path.into_inner().0,
config.get_ref().to_owned(),
))
}
fn build_post(file: &str, config: Config) -> String {
let mut post = None;
let (infos, toc) = get_post(
&mut post,
file,
&config.fc.name.unwrap_or_default(),
&config.locations.data_dir,
);
config.tmpl.render(
"blog/post.html",
BlogPostTemplate {
navbar: NavBar {
blog: true,
..NavBar::default()
},
post,
toc,
},
infos,
)
}
#[routes]
#[get("/blog/blog.rss")]
#[get("/blog/rss")]
pub async fn rss(config: web::Data<Config>) -> impl Responder {
HttpResponse::Ok()
.content_type(ContentType(MIME_TYPE_RSS.parse().unwrap()))
.body(build_rss(config.get_ref().to_owned()))
}