this static site generator
Jekyll and Hugo are overkill for me, so I wrote this small static site generator.
First, I write metadata files in TOML. These contain the post title for slug generation, the date, and a content source, which holds a path to a markdown body text. The generator reads post metadata files, converts the markdown body html, and finally renders a complete html file using a template. It’s about 50 lines of code.
post metadata
# post.toml
title = "some title"
date = 2021-05-31T00:00:00Z
content = "post.md"
The program uses glob
to read any .toml
files in the source directory. For each metadata file, it also reads the markdown file specified by content
.
// main.rs
// `?`s for brevity here.
for mdfile in glob("posts/**/*.toml")? {
let md: Metadata = toml::from_str(
&fs::read_to_string(mdfile?)?;
...
}
content
After reading the post body from the content
metadata key, the generator converts the markdown to HTML using the pulldown-cmark
crate.
// main.rs
let markdown = &fs::read_to_string(
format!("posts/{}", &md.content))?;
let mut html_out = String::new();
let parser = Parser::new_ext(&markdown, options);
html::push_html(&mut html_out, parser);
let mut ctx = Context::new();
ctx.insert("title", &md.title);
ctx.insert("content", &html_out);
tera.render_to(
"post.html",
&ctx,
File::create(
format!("public/{}.html", slugify(&md.title)))?
)?;
HTML templates
I wrote an HTML template for posts in the Tera template language.
The program combines metadata fields with the converted markdown to render a template like this one:
<!-- post.html -->
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<article>
{{ content }}
</article>
</body>
</html>