A simple static blog template based on markdown.
BS not included 🐄💩
- Clone this repo locally.
- Run it locally from /src With python:
python -m http.server 8080 - View the default template at localhost:8080
- Update for your content accordingly.
- Add the project to your own separate github repo.
- Host it for free on Netlify.
- Add posts & updates via pull requests to your github repo.
vanilla (adjective)
lacking distinction : plain, ordinary, conventional.
compost (noun)
A mixture or compound.
After running most of my personal websites on a VPS for over a decade, I decided it was time to migrate them to a more modern platform. Unfortunately, the options available on the market all felt bloated and over-engineered while somehow still lacking the user experience I was hoping for, so I started designing an alternative from first principles, like this. Vanilla compost sprouted from this exercise in design.
Static content should be static. HTML is simple enough. While CSS can get complex, the default version of this project only contains 15 lines of custom CSS.
Marked for parsing Markdown
If HTML is too thick for you, then maybe markdown is more your speed. It was created in 2004 to make formatting text easier than vanilla HTML & CSS, and has since become an established standard for readme files (like the one you're reading), static site generators, and other documentation platforms.
Marked parses markdown to HTML and can be included in an HTML page with a single line of code.
Bootstrap for UI
Bootstrap is a frontend toolkit that provides a lot of UI examples that only need 2 lines added to an HTML file to work. The Navigation for the default vanilla compost template (and all of my personal sites) is slimmed down version of this navbar.
JQuery for browser glue
Jquery is a JS library that's fast, small, and feature rich. Vanilla compost uses jquery to parse the name and content of the mardown file for a post and hand it to Marked to display in the browser. A lot of static site generators do this in either a build step or on the backend, which starts to take forever as a site grows larger. Pushing this compute step to the end user's browser just in time for them to view the post their looking for saves a lot of time and energy.
Parsing and generating the full list of available posts would eventually be more than Jquery could handle in the browser. Instead, I shifted this compute step left on our value stream towards the build step. generate_posts.py scans the markdown files in posts/, extracts a title (from a <!-- title: ... --> comment if present, otherwise the filename) and a date (from the post content, falling back to the file's modification time), sorts them newest first, and inserts the list into html_template.html in place of the <!-- posts--> marker to produce posts.html. No dependencies beyond the standard library - this used to run through Dominate, but both sites actually built on this template had already dropped it in favor of plain string handling, so the template followed suit. This can be executed locally while testing or run as part of a pipeline during your deployment process.