add: support a template.html file
This commit is contained in:
25
Cargo.lock
generated
25
Cargo.lock
generated
@@ -631,6 +631,12 @@ version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "memo-map"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
@@ -647,6 +653,17 @@ dependencies = [
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minijinja"
|
||||
version = "2.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12ea9ac0a51fb5112607099560fdf0f90366ab088a2a9e6e8ae176794e9806aa"
|
||||
dependencies = [
|
||||
"memo-map",
|
||||
"self_cell",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multipart"
|
||||
version = "0.18.0"
|
||||
@@ -841,7 +858,9 @@ dependencies = [
|
||||
"clap",
|
||||
"git2",
|
||||
"markdown",
|
||||
"minijinja",
|
||||
"rouille",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -899,6 +918,12 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
|
||||
@@ -8,3 +8,5 @@ clap = { version = "4.5.4", features = ["derive"] }
|
||||
git2 = "0.20.3"
|
||||
markdown = "1.0.0"
|
||||
rouille = "3.6.2"
|
||||
minijinja = { version = "2.1.0", features = ["loader"] }
|
||||
serde = { version = "1.0.203", features = ["derive"] }
|
||||
|
||||
@@ -16,3 +16,6 @@ The arguments supported include:
|
||||
|
||||
- --git-repo the URL of the git repo to load
|
||||
- --listen address to listen on, in the form of 0.0.0.0:8080
|
||||
|
||||
Additionally, if there is a './template.html' file in the repo, is will be used to wrap
|
||||
the generated HTML. Specifically, the 'body' block will be replaced by the markdown content.
|
||||
|
||||
69
src/main.rs
69
src/main.rs
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user