WIP: toc (#31)
Some checks are pending
ci/woodpecker/push/publish Pipeline is pending

This commit is contained in:
Mylloon 2023-05-02 23:10:36 +02:00
parent a310955757
commit e42c5492e8
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
4 changed files with 52 additions and 22 deletions

View file

@ -16,6 +16,7 @@ pub struct FileMetadata {
pub description: Option<String>, pub description: Option<String>,
pub publish: Option<bool>, pub publish: Option<bool>,
pub tags: Option<Vec<Tag>>, pub tags: Option<Vec<Tag>>,
pub toc: Option<bool>,
} }
#[derive(Content, Debug, Clone)] #[derive(Content, Debug, Clone)]

View file

@ -173,6 +173,7 @@ fn get_posts(location: &str) -> Vec<Post> {
#[derive(Content, Debug)] #[derive(Content, Debug)]
struct BlogPostTemplate { struct BlogPostTemplate {
post: Option<File>, post: Option<File>,
toc: String,
} }
#[get("/blog/p/{id}")] #[get("/blog/p/{id}")]
@ -190,47 +191,60 @@ pub async fn page(
fn build_post(file: String, config: Config, url: String) -> String { fn build_post(file: String, config: Config, url: String) -> String {
let mut post = None; let mut post = None;
let infos = get_post(&mut post, file, config.fc.name.unwrap_or_default(), url); let (infos, toc) = get_post(&mut post, file, config.fc.name.unwrap_or_default(), url);
config config
.tmpl .tmpl
.render("blog/post.html", BlogPostTemplate { post }, infos) .render("blog/post.html", BlogPostTemplate { post, toc }, infos)
} }
fn get_post(post: &mut Option<File>, filename: String, name: String, url: String) -> Infos { fn get_post(
post: &mut Option<File>,
filename: String,
name: String,
url: String,
) -> (Infos, String) {
let blog_dir = "data/blog"; let blog_dir = "data/blog";
let ext = ".md"; let ext = ".md";
*post = read_file(&format!("{blog_dir}/{filename}{ext}")); *post = read_file(&format!("{blog_dir}/{filename}{ext}"));
let (title, tags) = match post { let default = (&filename, Vec::new(), String::new());
let (title, tags, toc) = match post {
Some(data) => ( Some(data) => (
match &data.metadata.info.title { match &data.metadata.info.title {
Some(text) => text, Some(text) => text,
None => &filename, None => default.0,
}, },
match &data.metadata.info.tags { match &data.metadata.info.tags {
Some(tags) => tags.clone(), Some(tags) => tags.clone(),
None => Vec::new(), None => default.1,
},
match &data.metadata.info.toc {
// TODO: Generate TOC
Some(true) => String::new(),
_ => default.2,
}, },
), ),
None => default,
None => (&filename, Vec::new()),
}; };
Infos { (
page_title: Some(format!("Post: {}", title)), Infos {
page_desc: Some(format!("Blog d'{name}")), page_title: Some(format!("Post: {}", title)),
page_kw: Some( page_desc: Some(format!("Blog d'{name}")),
vec!["blog", "blogging", "write", "writing"] page_kw: Some(
.iter() vec!["blog", "blogging", "write", "writing"]
.map(|&tag| tag.to_owned()) .iter()
.chain(tags.into_iter().map(|t| t.name)) .map(|&tag| tag.to_owned())
.collect::<Vec<String>>() .chain(tags.into_iter().map(|t| t.name))
.join(", "), .collect::<Vec<String>>()
), .join(", "),
url, ),
} url,
},
toc,
)
} }
#[get("/blog/rss")] #[get("/blog/rss")]

View file

@ -261,3 +261,18 @@ pre:has(code.language-mermaid) {
margin: 20px; margin: 20px;
} }
} }
/* Table of content */
nav#toc {
position: fixed;
top: 0;
left: 25px;
margin-left: 50px;
}
@media only screen and (max-width: 1500px) {
/* Visible only on large screens */
nav#toc {
visibility: hidden;
}
}

View file

@ -22,7 +22,7 @@
<main> <main>
{{^post}} {{^post}}
<p>This post doesn't exist... sorry</p> <p>This post doesn't exist... sorry</p>
{{/post}} {{#post}} {{/post}} {{#post}} {{&toc}}
<article>{{&content}}</article> <article>{{&content}}</article>
{{/post}} {{/post}}
</main> </main>