bic
is an opinionated and minimal static site generator—with a focus on
blogs. View the demo or the source.
It uses Pandoc to convert plain Markdown files into HTML. They get templated {{Mustache}}-style with Mo. Hashids is used to generate IDs.
You get the (opinionated) basics of a static site/blog (read: opinionated):
pages/about.md
→ /about.html
posts/999-first-post.md
→ /first-post.html
drafts/998-untitled.md
→ /drafts/untitled.html
static/*
→ /*
For reproducible builds, I would recommend using bic
with Docker: ghcr.io/pinjasaur/bic:latest
Essentially, mount your source directory to /src
docker run --rm -v "$PWD":/src ghcr.io/pinjasaur/bic:latest
to spit out a build
directory with your generated site.
Alternatively, bic
is available as a nix flake.
Follow the setting up flakes guide to enable it, then run
nix run github:Pinjasaur/bic --command bic .
to run bic
in the current directory and spit out a build
directory with your
generated site.
bic
is strict where necessary to keep it opinionated with a lean scope.
pages/*.md
. Not nested.posts/*.md
and drafts/*.md
, respectively.
999-post.md
for the first post, 998-tacocat.md
for the second, et cetera. I would
recommend 3 or 4 digits for the Future Proof™.mtime
be used for the author’s discretion. However,
Git doesn’t record mtime
, so I would treat it as the “last
modified” date.#
to
signify the top-level heading./my-cool-post
not /posts/2021/my-cool-post.html
.For a fully-featured example, view the demo source code: https://github.com/Pinjasaur/bic-example
$ tree -F --dirsfirst
.
├── drafts/
│ └── 997-untitled.md
├── pages/
│ └── about.md
├── posts/
│ ├── 998-foo-bar.md
│ └── 999-hello-world.md
├── static/
│ ├── css/
│ │ └── style.css
│ ├── img/
│ │ └── photo.jpg
│ └── js/
│ └── script.js
├── __feed.rss
├── __index.html
├── _footer.html
├── _head.html
├── _header.html
├── entry.html
├── feed.rss
├── index.html
├── page.html
├── robots.txt
└── sitemap.xml
bic
uses an .env
pattern. This lets you configure required variables and add
any extras that can be used within your templates. Talk about batteries included.
A .env
file simply contains lines of KEY=value
pairs. If you, for whatever
reason, want to supply an environment variable at runtime and have it
override your .env
then use syntax such like:
ENV_VAR="${ENV_VAR:-default value}"
Not-100%-required but highly-recommended config:
SITE_AUTHOR
e.g. Captain Anonymous
(the site’s author)SITE_TITLE
e.g., My Cool Thing
(the site’s title)SITE_URL
e.g., https://domain.tld
(the site’s full base URL with no trailing slash)Optional, change if needed:
BIC_OVERWRITE
(disable file overwrite protection, see #caveats, default: unset)BUILD_DIR
e.g., _site
(configure output directory, default: build
)DATE_FORMAT
e.g., +%B %d, %Y
(passed into date
, default: +%F
→ YYYY-MM-DD
)SALT
e.g. super-random-abcxyz
(used to seed the Hashids encoding, default: bic
)TIMEZONE
e.g., US/Central
(the timezone you’re in, default: US/Central
)Anything listed above or added additionally to a .env
will be available
globally within templates.
Some specific keys used within entries (posts or drafts) and pages:
slug
, to be used in URL (does not contain the .html
file extension)title
, taken from first line of file # ...
date
, literally the mtime
of the fileid
, the number prefix for an entry encoded with Hashidsbody
, converted Markdown to HTML contents (sans title)Drafts will have a draft
key set. Likewise, posts will have a post
key set.
Each entry in posts/*.md
or drafts/*.md
is rendered against an entry.html
.
Each page in pages/*.md
is rendered against a page.html
.
index.html
and feed.rss
both use a double-underscore-prefixed template
partial of the same name e.g., {{__index}}
from __index.html
.
sitemap.xml
has access to an array of slugs with the slugs
key.
There is an order-of-operations for how files are built, as follows:
pages/*.md
posts/*.md
drafts/*.md
index.html
sitemap.xml
robots.txt
feed.rss
static/*
→ /
If you’re not careful, it’s possible you could overwrite an existing
file e.g. pages/test.md
and posts/999-test.md
both map to /test.html
. bic
uses the Bash builtin noclobber
e.g. set -o noclobber
to help prevent these
situations. This can be disabled by setting BIC_OVERWRITE
.
bic
in the wild:
bic
is built & maintained by Paul.