add: support a template.html file

This commit is contained in:
2025-12-17 22:53:23 -08:00
parent b2fab32d37
commit a01cda4566
4 changed files with 90 additions and 9 deletions
+60 -9
View File
@@ -1,9 +1,12 @@
use clap::Parser;
use git2::Repository;
use minijinja::Environment;
use rouille::Response;
use serde::Serialize;
use std::env;
use std::fs;
use std::path::Path;
use std::path::{Path, PathBuf};
/// A Rust-based wiki with markdown.
#[derive(Parser, Debug)]
@@ -18,12 +21,60 @@ struct Args {
listen: String,
}
fn render_markdown(path: &Path) -> Response {
match fs::read_to_string(path) {
Ok(md) => Response::html(markdown::to_html(&md)),
#[derive(Serialize)]
struct Context {}
fn render_page(repo_path: &PathBuf, path: &Path) -> Response {
let md = match fs::read_to_string(path) {
Ok(md) => md,
Err(e) => {
eprintln!("Error reading file {:?}: {}", path, e);
Response::text("Error reading file").with_status_code(500)
return Response::text("Error reading file").with_status_code(500);
}
};
let body_html = markdown::to_html(&md);
let template_path = repo_path.join("template.html");
if !template_path.is_file() {
return Response::html(body_html);
}
let template_str = match fs::read_to_string(&template_path) {
Ok(s) => s,
Err(e) => {
eprintln!("Error reading template file {:?}: {}", &template_path, e);
// Fallback to no template
return Response::html(body_html);
}
};
let context = Context {};
let mut env = Environment::new();
if let Err(e) = env.add_template("template", &template_str) {
eprintln!("Error adding template: {}", e);
return Response::text("Error rendering template").with_status_code(500);
};
let content = format!(
r#"
{{% extends 'template' %}}
{{% block body %}}
{}
{{% endblock %}}
"#,
body_html
);
if let Err(e) = env.add_template("content", &content) {
eprintln!("Error adding template: {}", e);
return Response::text("Error rendering populated template").with_status_code(500);
}
let tmpl = env.get_template("content").unwrap();
match tmpl.render(context) {
Ok(rendered) => Response::html(rendered),
Err(e) => {
eprintln!("Error rendering template: {}", e);
Response::text("Error rendering template").with_status_code(500)
}
}
}
@@ -52,18 +103,18 @@ fn main() {
if requested_path.is_dir() {
let index_path = requested_path.join("index.md");
if index_path.is_file() {
return render_markdown(&index_path);
return render_page(&repo_path, &index_path);
}
let readme_path = requested_path.join("README.md");
if readme_path.is_file() {
return render_markdown(&readme_path);
return render_page(&repo_path, &readme_path);
}
}
// Check if the path as-is is a file. e.g. /README.md
if requested_path.is_file() {
if requested_path.extension().and_then(std::ffi::OsStr::to_str) == Some("md") {
return render_markdown(&requested_path);
return render_page(&repo_path, &requested_path);
}
// For now, 404 on other file types. A real implementation might serve static files.
return Response::empty_404();
@@ -73,7 +124,7 @@ fn main() {
let mut md_path = requested_path;
md_path.set_extension("md");
if md_path.is_file() {
return render_markdown(&md_path);
return render_page(&repo_path, &md_path);
}
Response::empty_404()