Building a simple static website
I was tired of looking from the marketing of static website generators, and thought that it would be a great occasion to create one just for myself. After all, I probably don’t need 99% of the features of the latest frameworks.
The goal is pretty simple:
- Convert markdown files to html
- Wrap the content in a template
- Handle hot reload and conversion
With no further words let’s see how to do that.
Markdown conversion
For the markdown to html generation, we want to use
pandoc
:
# On Mac
brew install pandoc
# On Ubuntu/Debian
sudo apt-get install pandoc
We’ll create this project structure, with our content on the
src
folder, and the generated files in the
public
folder, ready to be distributed.
alexisfabre.fr/
├── src/
│ ├── index.md
│ ├── resume.md
│ └── articles.md
├── public/
├── metadata.yaml
├── template.html
└── convert.sh
The convert.sh
file will be the one to run when
we want to regenerate our content:
#!/bin/bash
# Create public directory if it doesn't exist
mkdir -p public
# Convert all markdown files to HTML
for file in src/*.md; do
filename=$(basename "$file" .md)
pandoc "$file" \
--template=template.html \
--metadata-file=metadata.yaml \
-o "public/$filename.html"
done
With that, we can use a general metadata.yaml
file and a template.html
in which we’ll put the
body from our markdown files:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$title$</title>
<style>
body { max-width: 800px;
margin: 40px auto;
padding: 0 20px;
font-family: sans-serif;
line-height: 1.6;
}margin-bottom: 2em; }
nav { </style>
</head>
<body>
<nav>
<a href="index.html">Home</a> |
<a href="resume.html">Resume</a> |
<a href="articles.html">Thoughts</a>
</nav>
$body$</body>
</html>
Here we can see the $title$
and
$body$
variables. The former can either come from
the metadata.yaml
file or the markdown files header
directly. The latter is the direct content of the markdown
files. Here is an example for index.md
with a
header including the title
variable:
---
title: Home
---
# Welcome to my website
This is my personal corner of the internet.
Now we can give permissions and execute
convert.sh
:
chmod +x watch.sh
./watch.sh
See our files generated in public
:
alexisfabre.fr/
├── src/
│ └── index.md
├── public/
│ └── index.html
├── metadata.yaml
├── template.html
└── convert.sh
Running the web server locally
We can easily set up a local web server using python
http.server
module:
python3 -m http.server
The files will be available at
http://localhost:8000
.
Hot rebuild
We want the conversion to be executed everytime we save our
source or template files. For this we will use
entr
, a file watcher utility tool:
# On Mac
brew install entr
# On Ubuntu/Debian
sudo apt-get install entr
The following script will watch for changes and automatically
call convert when you save a file in src
or
template.html
:
#!/bin/bash
# Start the Python HTTP server in the background
cd public
python3 -m http.server 8001 &
SERVER_PID=$!
cd ..
# Watch for changes and rebuild
find src template.html | entr -s './convert.sh'
# Clean up the server when the script is interrupted
trap "kill $SERVER_PID" EXIT
Note that it will run in port 8001
so we still
have our web server at port 8000
.
Give permissions to execute and run the watch.sh
script:
chmod +x watch.sh
./watch.sh
Conclusion
This was a great exercise to learn more about static website generation and file watching. I’m sure I’ll use this setup again in the future.