Like lots of folk on the internet, I have a website that's powered by a static site generator and hosted somewhere on the GitHub.
This post serves two functions:
-
Actually getting something that's text onto the internet.
-
Some self documentation on how this works, because as I've gone back to this over the past few months to add some polish, or just, make any kind of changes, I've been surprised by things that I've done for myself in the past.
Here are some immediately relevant links:
- The repo on github
- Zola - the static site generator I use, which is written in Rust
Branches, or the-details
vs master
Unlike the default github's repo-specific pages, you cannot use a gh-pages
branch
to host a site for a user. You end up having to create a repository called
<you>.github.io
, and whatever is on the master
branch will end up getting served
to the world. (source)
Luckily, we can set a default branch for the actual editing of
the code and content, and for some reason, I decided to call it the-details
.
Possibly because naming is hard.
README.md
A consequence here is that the README.md
cannot, by default sit in the
master
branch, explaining that you can't edit any content in that branch itself.
I have a workaround set up that symlinks the file from the static/
directory to ./
,
which means that it will always get deployed to master
(and the site) as
I push changes to it.
Update as of November 14th: This is also being used to keep track of the CNAME
file that GitHub looks for when setting up your own personal hosting.
$ cd static && ls -l
lrwxr-xr-x 1 stanistan staff 8B Nov 14 09:33 CNAME@ -> ../CNAME
lrwxr-xr-x 1 stanistan staff 12B Nov 14 09:33 README.md@ -> ../README.md
This was something that gave me piece of mind as I set this up, and later on was a pleasant surprise... I was worried about keeping the READMEs in sync across branches and learned that past Stan had already had that panic.
A lof of the setup for this static site is so I'm not suprised by things that are easy to forget. I expect to change this rarely and would rather it break meaningfully and with context on my laptop than suprisingly and live on the internet.
Configuration
There are two config files:
config.toml
- the prod configconfig.dev.toml
- the dev config
As of now, the only difference between the two is that I print out the
{{ __tera_context }}
at the bottom of each template in dev so that it's
easy to see what data is currently available while I'm futzing with the
templates.
Makefile
Besides the configuration difference in the toml
files, there is a structural
difference between dev
and prod
for this site.
By default, zola ships both the serve
and build
to the same public/
directory.
I've over-ridden these in the Makefile
so that one does not clobber the other.
public/
is in .gitignore
, and remains the path for watching live updates.
These can be triggered by running make serve-{dev,prod}
.
make serve-dev
- uses the dev config and shows draft postsmake serve-prod
- serves exactly what would be built and deployedmake build
- runszola build
but all output is in./dist
instead of./public
Content structure
Zola keeps all posts in the ./content
directory, which allows for arbitrary static
pages. I figured I didn't want everything to be a blog post (what about projects?),
and I also don't super like the term blog, even thouth that's what this is.
content/writes
is where all of the blog-ish content goes, and all of the posts
in it should be organized by date, in a writes/<YYYY>/<MM>/<DD>/<slug>/
format.
Zola doesn't have anything to help with autogenerating folder structures, so I made my own bash script to help. (see below)
Everything else (as of now) is a free for all.
$ find content -not -type d
content/writes/2019/11/09/how-this-blog-works.md <-- THIS POST
content/writes/2019/11/09/_index.md <-- autogenerated
content/writes/2019/11/_index.md <-- autogenerated
content/writes/2019/_index.md <-- autogenerated
content/writes/_index.md <-- redirects to /
content/_index.md <-- / the home page
Each of these autogenerated _index.md
files are linked to symlinked
from templates/writes_section
, so that when I want to change 'em, I
can do so easily.
Yes, this is all over-engineered, but also, kind of fun.
The Scripts
I've already covered make serve-{dev,prod}
and make build
which are wrappers
around their respective zola commands. These are a few of the
other scripts that make (pun somewhat intended), managing this easier.
-
bin/verify-content-dates
- (source)This script looks for all non
_index.md
files incontent/writes
and places them in the correct dates subdirectories. It also cleans up any directories/files left-over with no posts once that's done.It keeps it all neat.
aka:
make date-dirs
-
bin/ship
- (source)This script plublishes the
dist
directory to themaster
branch usinggit subtree split
. There was a bit of a gotcha with overriding the entire master branch using this because it has to have aCNAME
file and record in it to correctly publish tostanistan.com
, it is now being symlinked and copied over via thestatic/
directory, same as theREADME.md
.aka:
make deploy
For all of the scripts in bin/*
I'm using shellcheck
, which
is amazing, and helps me get better at writing bash.
The Theme
I'm using my own theme, which is being developed JIT, its primary colors come
from the inspired-github
syntax highlight theme
included in Zola.
- TODO (maybe): Extract into an actual theme.
Domain & Hosting
The domain is on dreamhost, which I've used for a loooong time, with DNS records pointed to GitHub as per these docs.