How am I building this?
As the mission of the site says, I want this to be uncomplicated AND I want to build most of this myself. I am aware that previous sentence is an oxymoron, so let's say re-phrase that:
I want to end up with an uncomplicated system, but I'm OK with writing some complex code.
Also, I want to re-use some parts of the layout in order to keep my sanity intact, so I will lay down some basic postulates:
- No bundlers are going to be used as long as it is possible. JS Modules to the rescue!
- TypeScript is allowed, but only when the need for more JavaScript arises.
- Since this site will mostly be static content, I'll write my posts in Markdown.
- In order to translate markdown to HTML, I will write a micro-framework in NodeJS.
- I will try to use as little packages from npm in development mode and I will explain each and every one of them.
- This site needs to have a search functionality, which will be a challenge in its own right. See below for 'why'.
- I am aware that there's a bunch of software serving this very purpose but I want to test the waters for myself.
Hosting
All that you can see here is being hosted on Github Pages,
which means that there is no fancy JavaScript framework behind it.
No fancy runtimes or anything similar. Just plain old static files.
I am aware that Github Pages are running on a cloud, but the point is that I
could host this on any machine that has even basic web server. We're going with the main philosophy of the site.
Search
Since all of this will be static content, I'll need to figure out how to index Markdown or HTML files and put them in service via IndexedDB or something similar. I have to admit that I'm not sure (yet) if it will ever work, but I'll give my best to make it.
Markdown, Drafts, Scripts and FrontMatter
So far, the only package added is marked and the only reason I'm adding it is because I'm only one guy with a day job and I want start posting in a reasonable amount of time. This way, I can focus on writing other parts of the system and posts, without worry of markdown's particularities. There's enough work already :).
I'm using a small script that I've written and which converts markdown documents to HTML using marked
. This conversion, of course,
happens at build phase, which happens locally. There might be some effort to move this to CI
some time in the future, but until I build enough of the basic infrastructure, I'll be satisfied with building locally.
I need to have some level of control about what you can see, so I'll need support for:
- drafts
- custom scripts for each page, so I can demo JS experiments
- meta stuff needed for SEO (description, keywords) in post
- likely some CSS overrides
- anything else, really
The easiest way to do this is by using front matter in Markdown. The snippet shown below is the initial version of fetching and parsing the front matter. It will evolve from this (it might already have by the time you're reading this) as I want to write a simple generalized yaml parser in the future. This version parses flat yaml structure nicely, but lacks the support for lists, which is something I'll tackle when I start adding JavaScript examples to my posts.
export function extractFrontMatter(markdown) {
export const frontmatterRegex = /^---\s*[\r\n]+([\s\S]*?)[\r\n]+---/;
const rawFrontMatter = frontmatterRegex.exec(markdown);
if (!rawFrontMatter) return {};
const frontmatter = Object.values(rawFrontMatter[1].split('\n')).reduce((o, value) => {
const [key, val] = value.split(':').map((item) => item.trim());
let parsedVal = val;
if (val === 'true') {
parsedVal = true;
} else if (val === 'false') {
parsedVal = false;
} else if (!Number.isNaN(Number(val))) {
parsedVal = Number(val);
}
return { ...o, [key.trim()]: parsedVal };
}, {});
return frontmatter;
}
Example of a markdown file
---
title: This goes to page's <title> element
draft: true|false
scripts:
- /assets/script-name.js
- /assets/another-script.js
---
# Title displayed in the page
Rest of the text that should be parsed by marked.