I built previous iterations of this static site here and on Neocities with Eleventy, which I use for my professional website(s) (industry-straddling nonsense). It's great for the use case of serving a site from a Git repository. My eleventy.config.js looks something like
export default function(eleventyConfig) {
eleventyConfig.setInputDirectory("src");
eleventyConfig.setOutputDirectory("docs");
eleventyConfig.addPassthroughCopy("src/_data"); // just site.js
eleventyConfig.addPassthroughCopy("src/c"); // stylesheet
eleventyConfig.addPassthroughCopy("src/m"); // assets
};
because instead of deploying from the default branch on GitHub, I use this trick from Léa Tortay. However! The end result can be a bit over-engineered for my purposes. For example, if my src/ looks like
src/
|-- epistles/
| |-- arch.md
| |-- autobio.md
| |-- dotfiles.md
| |-- index.md
| |-- markdown.md
| `-- {et cetera...}
`-- writing/
|-- court-of-cups.md
|-- index.md
|-- strawman-cards.md
|-- suit-of-cups.md
`-- the-stars-have-all-gone.md
Eleventy turns it into... this thing.
docs/
|-- epistles/
| |-- arch/
| | `-- index.html
| |-- autobio/
| | `-- index.html
| |-- dotfiles/
| | `-- index.html
| |-- markdown/
| | `-- index.html
| |-- {et cetera...}
| `-- index.html
`-- writing/
|-- court-of-cups/
| `-- index.html
|-- strawman-cards/
| `-- index.html
|-- suit-of-cups/
| `-- index.html
|-- the-stars-have-all-gone/
| `-- index.html
`-- index.html
This doesn't bother me in the slightest hosting my sites on GitHub or Codeberg Pages, but I've yet to pull the trigger on a Nekoweb Patreon membership. Why? I truly don't know. It's $3. My stubborn refusal to spend money on fandom is colliding with my true love for and reliance on Nekoweb's mission. I will shape up after posting this and become a supporter.
But I still think the 11ty output is deranged for my needs. I really am not making anything crazy, as you can see, so I've been tinkering with Jinja2 purely for the work of converting Markdown files to HTML using templates. Most of the logic in the build script goes toward constructing the _site (what actually goes on Nekoweb). You can look at it right here, but the gist is:
- Create
.htmloutput path for each.mdfile - Append any directories in front of those
.htmlpaths to create links - Use jinja2 to convert .md to .html; steps 1 and 2 just created their names/paths!
- Create file tree entry for each item whether it's a dir (like
assets/,archive/,blog/) or HTML. - Take those entries and make each directory's internal tree.
- Smush steps 4 and 5 together to make the entire site's file tree.
- Format this file tree into the
index.htmlwith the only other jinja2 template I have, with special handling to put the faux README first.
The point of all this, really, is so my _site resembles src as much as possible apart from the Markdown files being HTML—so to avoid having dozens of files called index.html nested in directories solo, both annoying to update in the Nekoweb dashboard individually and unwieldy to navigate. With 11ty, you hardly have a reason to hang out in your output directory at all, but I've created this problem for myself that I can easily solve by supporting Nekoweb and getting Neko FTP and Neko Git. Sigh. Even when I do, I'll still use my little Python generator because I see no reason for my file tree to have such tiny branches that just end with index.html.
Now my file structure is pretty much what you see on my homepage, except with .gifs pruned and, as mentioned, the README first. I went from epistles/ -> blog/ and writing/ -> archive/ in part to leverage alphabetical order in my aesthetic file tree homepage since I care more about my fanfiction than my blog posts. Of course, they both have corresponding data serialization: RSS XML for the blog and a .json for the archive.
Because I'm insufferable/have these habits, here's my actual project directory, kept in a private Codeberg repo:
nekoweb/
|-- assets/ # "passed through" to _site 11ty-style, minus most image extensions
|-- __pycache__/
|-- _site/ # uploaded to Nekoweb
|-- src/ # pure Markdown
|-- templates/ # for Jinja2
|-- build.py
|-- deploy.sh
|-- Makefile # literally just build.py && deploy.sh
|-- pyproject.toml # just so I can use uv
`-- uv.lock
deploy.sh is my workaround in place of a live server. I do all my dev work SSH'd into a clamshelled MacBook Air 2017, so to preview this site I just rsync the contents of _site onto my desktop and open it in qutebrowser or LibreWolf. So my Makefile is just
serve:
uv run -m build && ./deploy.sh