post pathing
This commit is contained in:
116
src/main.rs
116
src/main.rs
@@ -1,12 +1,75 @@
|
||||
use axum::{
|
||||
Router, response::Html, routing::get
|
||||
Router, extract::Path, response::Html, routing::get
|
||||
};
|
||||
use tower_http::services::ServeDir;
|
||||
use askama::Template;
|
||||
use markdown::to_html;
|
||||
use std::fs;
|
||||
// use typst::model;
|
||||
// use typst_html;
|
||||
use std::{collections::HashMap, fs, io::{Error, Write}, process::{Command, Stdio}};
|
||||
use regex::Regex;
|
||||
|
||||
|
||||
|
||||
fn load_posts() -> Result<HashMap<String, Post>, Error> {
|
||||
|
||||
let dirs = fs::read_dir("static/posts")?;
|
||||
|
||||
let re_title = Regex::new(r#"#let\s+post_title\s*=\s*"([^"]*)""#).unwrap();
|
||||
let re_summary = Regex::new(r#"#let\s+post_summary\s*=\s*"([^"]*)""#).unwrap();
|
||||
|
||||
let mut posts: HashMap<String, Post> = HashMap::new();
|
||||
for dir in dirs {
|
||||
let typst_path = dir?.path().join("post.typ");
|
||||
let typst = fs::read_to_string(typst_path).expect("Failed reading post");
|
||||
let title = re_title.captures(&typst)
|
||||
.expect("Post title not found")
|
||||
.get(1).unwrap().as_str().trim().to_string();
|
||||
let summary = re_summary.captures(&typst)
|
||||
.expect("Post summary not found")
|
||||
.get(1).unwrap().as_str().trim().to_string();
|
||||
let slug = title.clone().replace(" ", "-").to_lowercase();
|
||||
posts.insert(
|
||||
slug.clone(),
|
||||
Post {
|
||||
title: title.clone(),
|
||||
slug: slug,
|
||||
preview_image: "NA".to_string(),
|
||||
summary: summary,
|
||||
render: Html(PostTemplate {
|
||||
title: title,
|
||||
content: typst_to_html(typst),
|
||||
}.render().expect("Failed rendering post")),
|
||||
}
|
||||
);
|
||||
}
|
||||
Ok(posts)
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "post.html")]
|
||||
struct PostTemplate {
|
||||
title: String,
|
||||
content: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug)]
|
||||
struct Post {
|
||||
title: String,
|
||||
preview_image: String,
|
||||
summary: String,
|
||||
slug: String,
|
||||
render: Html<String>
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Template)]
|
||||
#[template(path = "posts.html")]
|
||||
struct PostsTemplate {
|
||||
posts: Vec<Post>
|
||||
}
|
||||
|
||||
// Template for home
|
||||
#[derive(Template)]
|
||||
#[template(path = "home.html", ext = "html")]
|
||||
@@ -14,21 +77,58 @@ struct HomeTemplate {
|
||||
content: String
|
||||
}
|
||||
|
||||
fn typst_to_html(typst: String) -> String {
|
||||
let mut child = Command::new("typst")
|
||||
.args(["compile", "-", "-", "--format", "html", "--features", "html" ])
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("Failed running typst");
|
||||
let mut stdin = child.stdin.take().expect("Failed opening STDIN");
|
||||
stdin.write_all(typst.as_bytes()).expect("Failed writing to STDIN");
|
||||
drop(stdin);
|
||||
|
||||
let output = child.wait_with_output().expect("Failed reading output");
|
||||
String::from_utf8_lossy(&output.stdout).to_string()
|
||||
}
|
||||
// , posts: &Vec<Post>
|
||||
async fn get_post(
|
||||
Path(slug): Path<String>,
|
||||
posts: HashMap<String, Post>
|
||||
) -> Html<String> {
|
||||
if posts.contains_key(&slug) {
|
||||
return posts[&slug].render.clone()
|
||||
}
|
||||
else {
|
||||
return Html("404".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
||||
let home_html = Html(
|
||||
HomeTemplate {
|
||||
content: to_html(&fs::read_to_string(
|
||||
"static/strings/home.md"
|
||||
).expect("Couldnt read file"))
|
||||
}.render().unwrap()
|
||||
content: typst_to_html(fs::read_to_string(
|
||||
"static/home.typ"
|
||||
).expect("Couldnt read file"))
|
||||
}.render().expect("Failed rendering home template")
|
||||
);
|
||||
|
||||
let posts: HashMap<String, Post> = load_posts().expect("Failed loading posts");
|
||||
let posts_html = Html(
|
||||
PostsTemplate{
|
||||
posts: posts.values().cloned().collect::<Vec<Post>>()
|
||||
}.render().expect("Failed rendering posts")
|
||||
);
|
||||
|
||||
let site: Router = Router::new()
|
||||
.route("/", get(home_html))
|
||||
.nest_service("/static", ServeDir::new("static"));
|
||||
.route("/posts", get(posts_html))
|
||||
.route("/posts/{title}", get(|title| get_post(title, posts)))
|
||||
.nest_service("/static", ServeDir::new("static"))
|
||||
// .with_state(posts)
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user