Update server post and fix post titles

This commit is contained in:
2025-10-29 19:02:55 +08:00
parent 185d9d4d63
commit c584d39607
8 changed files with 493 additions and 61 deletions

View File

@@ -1,17 +1,28 @@
use crate::post_manager::PostManager;
use crate::git_tracker::get_git_version;
use crate::post_manager::PostManager;
use std::collections::HashMap;
use std::fs;
use std::future::Future;
use std::pin::Pin;
pub fn render_template(
pub async fn render_template(
template: &str,
post_manager: &PostManager,
current_post: Option<&str>,
) -> Result<String, String> {
parse_template(template, post_manager, current_post, 0)
parse_template(template, post_manager, current_post, 0).await
}
fn parse_template(
fn parse_template<'a>(
template: &'a str,
post_manager: &'a PostManager,
current_post: Option<&'a str>,
depth: usize,
) -> Pin<Box<dyn Future<Output = Result<String, String>> + Send + 'a>> {
Box::pin(async move { parse_template_impl(template, post_manager, current_post, depth).await })
}
async fn parse_template_impl(
template: &str,
post_manager: &PostManager,
current_post: Option<&str>,
@@ -32,7 +43,8 @@ fn parse_template(
// Try to parse tag
if let Some((tag_name, attrs, end_pos)) = parse_tag(&chars, i) {
// Process tag immediately based on type
let content = process_tag(&tag_name, &attrs, post_manager, current_post, depth)?;
let content =
process_tag(&tag_name, &attrs, post_manager, current_post, depth).await?;
result.push_str(&content);
i = end_pos;
continue;
@@ -140,7 +152,7 @@ fn parse_tag(chars: &[char], start: usize) -> Option<(String, HashMap<String, St
}
}
fn process_tag(
async fn process_tag(
tag_name: &str,
attrs: &HashMap<String, String>,
post_manager: &PostManager,
@@ -149,7 +161,8 @@ fn process_tag(
) -> Result<String, String> {
match tag_name {
"include" => {
let src = attrs.get("src")
let src = attrs
.get("src")
.ok_or_else(|| "include tag missing 'src' attribute".to_string())?;
let include_path = format!("templates/{}", src);
@@ -157,7 +170,7 @@ fn process_tag(
.map_err(|e| format!("Failed to read include file '{}': {}", src, e))?;
// Recursively parse the included content
parse_template(&content, post_manager, current_post, depth + 1)
parse_template(&content, post_manager, current_post, depth + 1).await
}
"post-html" => {
@@ -166,28 +179,43 @@ fn process_tag(
let post = post_manager
.get_post(post_name)
.await
.ok_or_else(|| format!("Post '{}' not found", post_name))?;
Ok(post.html_content.clone())
}
"title" => {
let post_name = current_post
.ok_or_else(|| "title tag used outside of post context".to_string())?;
if let Some(post_name) = current_post {
let post = post_manager
.get_post(post_name)
.await
.ok_or_else(|| format!("Post '{}' not found", post_name))?;
let post = post_manager
.get_post(post_name)
.ok_or_else(|| format!("Post '{}' not found", post_name))?;
let none: String = "".to_string();
let pre = attrs.get("pre").unwrap_or(&none);
let postfix = attrs.get("post").unwrap_or(&none);
Ok(post.title.to_string())
Ok(format!("{}{}{}", pre, post.title, postfix))
} else {
let def = attrs
.get("default")
.and_then(|s| Some(s.clone()))
.unwrap_or("<title not set>".to_string());
Ok(def.to_string())
}
}
"updated" => {
// Insert the last updated time of the current post (or most recent post)
let post_ts = if let Some(p) = current_post {
post_manager.get_post(p).ok_or_else(|| format!("Post '{}' not found", p))?.modified_at
post_manager
.get_post(p)
.await
.ok_or_else(|| format!("Post '{}' not found", p))?
.modified_at
} else {
post_manager.get_update_timestamp()?
post_manager.get_update_timestamp().await?
};
Ok(post_ts.format("%Y-%m-%d").to_string())
@@ -200,13 +228,12 @@ fn process_tag(
}
"post-list" => {
let limit = attrs.get("limit")
.and_then(|s| s.parse::<usize>().ok());
let limit = attrs.get("limit").and_then(|s| s.parse::<usize>().ok());
let posts = if let Some(l) = limit {
post_manager.get_posts_limited(l)
post_manager.get_posts_limited(l).await
} else {
post_manager.get_all_posts()
post_manager.get_all_posts().await
};
let mut list_html = String::from("<ul class=\"post-list\">\n");
@@ -214,7 +241,7 @@ fn process_tag(
list_html.push_str(&format!(
" <li><a href=\"/p/{}\">{}</a> <span class=\"date\">{}</span></li>\n",
post.name,
post.name,
post.title,
post.created_at.format("%Y-%m-%d")
));
}
@@ -223,7 +250,7 @@ fn process_tag(
Ok(list_html)
}
_ => Err(format!("Unknown tag: {}", tag_name))
_ => Err(format!("Unknown tag: {}", tag_name)),
}
}