rolling your own
I've only been writing html / css / js fror my day job for 5+ years. Naturally I was very intimidated when it came time to make my own site.
In some ways that actually makes sense. There's a pressure to have these 5+ (really only ~3 or so, I switched off of frontend eventually) years of professional experience reflected in what I make. Also I'm aware of exactly how complex serving some divs can really be. Not to mention the sheer number of choices you have when it comes down to existing frameworks and tools.
But in the end, I wanted a site to host my writing and art. Would using an existing framework have helped me get from nothing to a working site faster? Maybe. But between having to choose a framework, set it up, and learn how it works, rolling my own seemed faster.
Another factor was flexibility; my use-case is fairly unique in that I wanted to have art and writing, and maybe even some code demos. There probably are frameworks out there that do both, but again, I wasn't sure if it was worth the time to figure out what they were. Also as frameworks get more flexible, they usually become more complex or do less for you.
In the end, the biggest pre-existing tool I used was jinja2 for html templating, and some python libs for markdown to html. Everything else is ~200 lines of python. It took a while to write them, but totally worth the time I saved not researching, and it does exactly what I want. Roughly the flow is:
- read site structure and content from toml
- post-processing
- call jinja with processed data
- copy-over manually created vanilla css and js files
So far everything's simple enough that I didn't need any other tools. Maybe if the site gets more complex or I want to support more features I'll look into some javascript libs or sass, but for now it's simple and works great.
data specification
I hate writing html, so I wanted to be able to generate new pages with as little html as possible, and in a way that didn't feel like coding. Ideally you'd write a bit of config the build script makes into html for you. When designing this data => page specification, I wanted it to be:
- human readable
- with minimal repetition
To that end I chose TOML (as a config language with good ergonomics). To make a new page, you'd write something like this.
[[content]]
id = 'the_sculptor'
name = 'The Sculptor'
path = 'the_sculptor.html'
tags = ['short_story', 'writing']
description = 'A surpassing sculpture, and its sculptor.'
date = '2018-04-13'
preview_image = "preview/sculpture.jpg"
Anything else needed for page generation is handled by python in data post-processing.
For example, many of the individual pages are part of a series. It would be simple enough to link these together but instead, I opted to define a "seris" abstraction and handle the pagination and other shared properties in python.
[[series]]
name = 'bta_mainline'
item_id = 'bta_mainline_{}'
item_name = "Beyond the Awakening: Mainline {}"
path = 'bta_{}.jpg'
suffixes = ['01', '02', '03']
shared_tags = ['art', 'comic', 'beyond_the_awakening', 'digital']
Individual pages can still be specified to overwite data shared to the series.
[[content]]
id = 'bta_mainline_01'
description = "Something falls from Rumreign's star-ridden sky."
alt = """A meteor streaks over a trail of craters. \
From the largest extends a tower. \
The sky is filled with stars, the silhouette of a gas giant."""
date = '2022-01-29'
pinned = true
I suspect that it would be hard to find an existing framework with this particular abstracting without still writing some custom code.
My one departure from the principles of the design was manually specifying an id. While this id probably could have been generated from the name, this id gets used as the url (for now) and I'm paranoid about dead links. It also ended up being a nice convenience for ad-hoc links between pages.
site navigation
Content generated, I already had a pretty solid model of how I wanted users to be able to find it. In short, tags, everywhere.
The "main sections" of site navs are just links to the same page that does the tag search. They're only privileged in that they get a link on the nav bar, and they get used if there isn't a preview image generated otherwise. The "home" page of the site is also just a tag search page, but with some pinned results for the "most important" stuff. This means there are only two kinds of pages on the site: content pages and search pages.
I have strong feelings about the "right" way to do search--this is it, by the way.
improvements?
Honestly probably won't feel the need to change anything til I try to upload a some code demo and everything breaks. I might go ahead and do a rewrite at that point as well. The python code is probably 3/10 on the spaghetti scale (which is honestly pretty manageable since it's <200 lines), where as the js is maybe 6/10. I also resent having to write javascript (maybe a topic for another blogpost? But there are plenty of people who have pointed out how javascript is a wild language) so I might find myself breaking my vow of library aestheticism for some kind of transpiler.
But for now I'm content. I'm finding it simple and fast to add a new page, and even weird things like a contact / about page are well-covered by existing things I've written already like the inline-markdown handler that I use for these blog posts. Like all good tools, the site gets out of the way for what I'm using it for.