124 lines
3 KiB
Rust
124 lines
3 KiB
Rust
use actix_web::{
|
|
get, http::header::ContentType, routes, web, HttpRequest, HttpResponse, Responder,
|
|
};
|
|
use cached::proc_macro::cached;
|
|
use ramhorns::Content;
|
|
|
|
use crate::{
|
|
config::Config,
|
|
logic::blog::{build_rss, get_post, get_posts, Post, BLOG_DIR, MIME_TYPE_RSS, POST_DIR},
|
|
template::{InfosPage, NavBar},
|
|
utils::{
|
|
markdown::{File, FilePath},
|
|
metadata::MType,
|
|
misc::{lang, make_kw, read_file_fallback, Html, Lang},
|
|
},
|
|
};
|
|
|
|
#[get("/blog")]
|
|
pub async fn index(req: HttpRequest, config: web::Data<Config>) -> impl Responder {
|
|
Html(build_index(
|
|
config.get_ref().to_owned(),
|
|
lang(req.headers()),
|
|
))
|
|
}
|
|
|
|
#[derive(Content, Debug)]
|
|
struct BlogIndexTemplate {
|
|
navbar: NavBar,
|
|
about: Option<File>,
|
|
posts: Vec<Post>,
|
|
no_posts: bool,
|
|
}
|
|
|
|
#[cached(time = 60)]
|
|
fn build_index(config: Config, lang: Lang) -> 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, html_lang) = read_file_fallback(
|
|
FilePath {
|
|
base: blog_dir,
|
|
path: "about.md".to_owned(),
|
|
},
|
|
MType::Generic,
|
|
&lang,
|
|
);
|
|
|
|
// 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"])),
|
|
},
|
|
Some(html_lang),
|
|
)
|
|
}
|
|
|
|
#[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,
|
|
None,
|
|
)
|
|
}
|
|
|
|
#[routes]
|
|
#[get("/blog/blog.xml")]
|
|
#[get("/blog/blog.rss")]
|
|
#[get("/blog/rss.xml")]
|
|
#[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()))
|
|
}
|