7.6 KiB
{{{ "title": "Architecture", "last_tended_to": "1/15/2025", "planted": "11/26/2025", "status": "sprouted" }}}
The styling and functionality of this page is inspired by (stolen from) WikiWikiWeb. The corkboard-esque styling with "receipt pages" are the most obvious aspect, but not the only one. WikiWikiWeb also utilizes a custom markup language to write and edit pages, then translates that on the client-side to HTML which is added directly to the DOM. I do something similar using Markdown backing files (with minor preprocessing) translated with marked.js.
I tried to build this website to be as simple as possible. This has two main focuses:
- I want to be able to write simple Javascript without any extensions. No NPM, no Typescript, no compilation.
- I want to be able to write my pages and immediately see the results. I shouldn't need to kick off bulky static site generation before making a page accessible.
Both of these goals aim to minimize the friction of creating as much as possible. I'm not a frequent writer and I don't have much time, so I'd like to remove all barriers that could prevent me from working on this. Also I hate the web development ecosystem.
Corkboards & receipts
I'm not sure what else to call this style of overlaid, thin pages placed on top of links. The thin-and-tall articles remind me of receipts and the fact that they just end up strewn about (monitor space providing) feels a lot like pinning things to a corkboard.
It's a relatively simple effect to achieve--simply interrupt the standard onClick handler for internal links and parse it for the page to request. Once you've received the file, process it into HTML to be added to the DOM in a styled div. They're placed with the top left corner where the mouse position was, clamped so that it doesn't go off the screen for better usability on small devices.
Formatting
This is one of the more complicated things going on. I do two main formatting steps: front matter and page imports. There's also a quick step that adds the visitor counts to each page.
Front Matter (Kinda)
Front matter is a way of annotating a markdown document with additional data that will not be displayed. It's typically done in YAML and there are plenty of NPM packages to handle it, but I don't need a missile for this molehill. I decided to stick with built in Javascript JSON parsing to gather the data and store it at the beginning of each file with an additional two pairs of outer braces:
{{{ "front": "matter" }}}
This data is parsed and stripped before translating the markdown to HTML. I use it to generate the title and metadata, as well as set a few display settings.
Inlining pages
For my Twitter archive I wanted standalone files so that I could reuse/organize my tweets as I see fit. If I were to stick to keeping everything standalone, this would've led to link-cities full of tiny standalone tweet pages, which didn't feel accessible and wasn't fun to navigate. Instead, I decided to add a way to "inline" pages--putting the link into the Markdown and replacing it with a copy of the linked page. My preprocessing step looks for links formatted as:
[[[pagename]]]
then replaces them with the content of the page in the preprocessing step. This is done synchronously for the first 2 inlined pages, but to prevent slowing down the loading of pages with more inlining, the rest of the pages are replaced with placeholders to be loaded asynchronously.
Visit counts (footsteps)
You may have noticed the visit counts that now appear at the bottom of each page. These are linked to the next topic, but are related to page formatting so worth mentioning here. After the entire page is loaded and preprocessed I request a file containing the corresponding per-page counter and manually add it to the HTML for the page--you'll hopefully never see it, but if I mess up and can't track the number of visits on a page it'll say that the page has been visited "an unknown number of times".
Interactivity
This is the one part of my website which I think strays further from my K.I.S.S mindset. Before adding my page to Neocities, I wanted to add a guestbook. Many "Neocitizens" do this by using a third party guestbook service. This might've been a better idea (captcha, standardization, spam protection), but I feel like it goes against two things:
- I'm trying to be part of a more decentralized internet
- I like to program
So I decided to build my own backend webserver. I also wanted to keep with the files-first organization of my other setups--if all my dynamic applications die, I still want my content to be in easily interpretable files to recover later. Files are also convenient because if something goes wrong, I can just delete them, edit them, or disable access to them altogether.
The webserver is incredibly simple. I built it in Rust with Warp--not for any particular architectural or opinionated reason, but just because that's the combination I felt I would have fun working with. It's incredibly barebones--it literally exposes 2 HTTP POST request endpoints which take the absolute minimum amount of data. I did NOT want to use JSON again, I get enough of that at my job.
Signing the Guestbook
The first of the two endpoints requires the request body to be the content of the "signature". It accepts the request and does the following:
- Figures out the time of the month. It's nice to have an idea when someone interacted with my page, but I don't want to feel like I'm snooping on your internet history/habits. Sometimes marking a comment with the exact timestamp feels like I'm being snitched on--and I don't want to contribute to the Panopticon of the internet. Therefore, I decided that I'd only figure out the date that a signature was made--and to add some character, I decided to round the date into where in the month it is (early, mid, or late). This is the header of each signature.
- Adds a line break and the time of month to the bottom signatures file. I decided to make the guestbook a single file so that it's easy to maintain and only requires a single inline embed to display. This kept me from having to write any complicated dynamic loading code to load a bunch of signatures to the guestbook page.
- Adds the content of the signature to the guestbook file.
That's it. The most complicated part is the time of month calculation. Other than that, it's just a complicated "append to file" routine.
Stepping through the Garden
I was feeling a little bit like I was shouting into the void when I was first working on this website. I was annoying all of my friends and family about it constantly, and a few of them were checking it (and consistently, thank you!!) but I never got to see that. The site felt lonely. When I added the ability to do some dynamic elements to the website, I decided I'd also put in some work to keep track of how many visitors each page gets. I don't bother (or want to bother) with tracking who visits a page--see above on the "internet panopticon". Therefore, I exposed the second endpoint which literally does 2 things:
- Looks at the URL requested
- Finds (or creates) the file associated with that URL and increases the counter inside of it.
Despite how simple it is, it works really well. I store all of the "footstep" files in a single directory and can read them back whenever I want to display how many people have visited a page. I'm quite happy with it.