- Why Blog?
- Blogging, Take 1
- Blogging, Take 2
- How hmlhml.com Works
- The Templates
- Serving hmlhml.com
- What's Next?
Why Blog?
I’ve wanted to write a blog for awhile, mostly for these reasons
- I’m a self taught software engineer, other people blogging about tech has been invaluable to my learning
- People at work are getting tired of hearing my opinions, so they probably need a different venue
Blogging, Take 1
This is actually my second attempt at writing a blog. My first attempt is a half finished attempt of writing a static site generator from scratch in Elixir. My big learning from the first attempt is to get something working as fast as possible, and then progressively enhance as features come up.
Side Note, Why not medium.com?
I don’t have anything against medium.com, I’m not a fan of the “You’ve exceeded the number of articles you can write per month” thing, but it’s not that big of a deal to me. Honestly, most of my inspiration for doing interesting projects in tech aligns with this PR adding N64 support to the Linux kernel
> Hi all,
>
> Here's a port for the Nintendo 64.
>
> At least two people have done such a port before, but didn't submit.
> This is not based on either.
>
> RFC because I'm not sure if it's useful to have this merged. Old,
> niche, and limited platform.
>
> "But why", I hear from the back. Having Linux available makes it easier
> to port emulators and fb or console games.
> www.linux-mips.org/wiki/Nintendo_64 can be edited to no longer say
> "vaporware".
> Most importantly, because I can.
Why build my own blog engine? Most Importantly, because I can
Blogging, Take 2
hmlhml.com is my second attempt at blogging. My big goal is get something online. Ideally it meets all the following goals I have for my blog.
Goals for my Blog
- Compiles to a folder of files (nothing which requires a special server/database)
- Minimal effort to add a new article
- Automatically generates a homepage with list of all articles
- I’d like to only write markdown, and have it be served as html
- Fast compile/see in browser loop
- Domain name + SSL
- Plays nice with Arch+Vim
- 100% self hosted
- Send the absolute minimum amount of data to people on the other end of the wire (I don’t need megabytes to serve some text!)
- Looks good in iPhone “reader view”, the greatest thing the iPhone has ever done
Non Goals (for Now)
- Tags
- Mailing List
- Search
- Ads
- Plays nice with everything that isn’t Arch+Vim
How hmlhml.com Works
Folder Structure
Making a new Article
The first thing I do to start writing a new article is use my new-article.sh
script to create a new file in the articles/
directory.
Here is ./new-article.sh
NOW=`date "+%Y-%m-%d"`
touch "./articles/${NOW}__${@}.md"
So to create an article called foo-bar-baz
./new-article.sh foo-bar-baz
Will create a file called 2020-12-26__foo-bar-baz.md
in the articles directory
Generating the blog
I use the script generate-blog.sh
in order to create the _build
folder with the compiled, ready to serve, blog.
# Read CSS and export it as a variable
export CSS=$(cat ./blog.css)
# If there is a pre-existing `_build` directory, remove it.
# Next make a new empty `_build` dir
echo "-- Cleaning _build directory" && echo
rm -rf ./_build && mkdir ./_build
# Copy over all the static stuff (Images mostly)
echo "-- Copying static files" && echo
cp -r ./static/* ./_build/
echo "-- Processing articles"
mkdir -p ./_build/articles
mkdir -p ./_build/_tmp
# For each article file (with relative path) sorted in reverse
for ARTICLE in $(ls -d ./articles/* | sort -r); do
# take just the filename without the markdown extension
BASENAME=`basename -s .md $ARTICLE`
echo " * Processing $BASENAME"
# All articles filenames follow YYYY-MM-DD__article-title-etc-etc
# Here we break the file name into the date and title
export ARTICLE_TITLE=$(echo $BASENAME | sed "s/.*__//" | tr "-" " ")
export ARTICLE_DATE=$(echo $BASENAME | sed "s/__.*//")
# Here we convert the markdown into html
# one cool piece is `+toc` which puts the table of contents in
export ARTICLE_CONTENTS=$(cat $ARTICLE \
| markdown -T -S -f +links,+image,+html,+strikethrough,+fencedcode,+toc)
# Take all the env vars we created for this article
# use `envsubst` on the base template
cat ./template__article.html | envsubst \
> ./_build/articles/$BASENAME.html
# Collect all the links to the article in a temporary file
cat <<- LINK >> ./_build/_tmp/article-links.html
<div class='article-link'>
<a href='./articles/$BASENAME.html'>$ARTICLE_TITLE</a>
</div>
LINK
done
echo && echo "-- Building Index" && echo
# Build the homepage, by putting the article links into it via `envsubst`
export ARTICLE_LINKS=$(cat ./_build/_tmp/article-links.html)
cat ./template__index.html | envsubst > ./_build/index.html
rm -rf _build/_tmp
The Templates
The article and index templates are written in HTML with $VAR
interpolation
template__index.html
<html>
<head>
<title>HMLHML</title>
<style>
$CSS
</style>
</head>
<body>
<h1 class="blog-title center-text">HMLHML - Half Moore's Law, Half Murphy's Law</h1>
<h2 class="center-text">Unsolicited opinions on tech</h2>
<div class="article-links title-case center-text">$ARTICLE_LINKS</div>
<div class="contact center-text">
<a href="https://github.com/grantjamespowell">Github</a> -
<a href="./gpg-key.txt">GPG key</a>
</div>
</body>
</html>
template__article.html
<html>
<head>
<title>$ARTICLE_TITLE - HMLHML</title>
<style>
$CSS
</style>
</head>
<body>
<h1 class="blog-title"><a href="../"><b>HMLHML - Half Moore's Law, Half Murphey's Law</b></a></h1>
<h1 class="article-title title-case">$ARTICLE_TITLE</h1>
<h3>Written by <a href="https://github.com/grantjamespowell">Grant Powell</a> on $ARTICLE_DATE</h3>
<div class="article-contents">$ARTICLE_CONTENTS</div>
</body>
</html>
Formatting
One of my favorite trends in programming is the popularity of tools like mix format and go format. I found out I can do a similar thing in my browser using the prettier tool. As a lightweight integration in vim I can use :%!prettier --parser html
which pipes the contents of the current file into prettier and replaces the contents with the result
Serving hmlhml.com
I have a little box I keep running on Digital Ocean I’d like to use it to serve hmlhml.com.
Getting the content to the server
While ssh’d into the server running hmlhml.com, I create a directory to hold the blog content
sudo mkdir -p /www/data/blog
sudo chown -R `whoami` /www/data/blog
Locally I “push” the content to the /www/data/blog
folder using the script ./deploy.sh
which has the following content
rsync -rv _build/* gp@hmlhml.com:/www/data/blog/
Serving the content
After installing nginx
(apt install nginx
), I’m going to configure my nginx
process to server the /www/data/blog
dir as hmlhml.com
In the file /etc/nginx/sites-enabled/blog
I add the following
server {
server_name hmlhml.com;
location / {
root /www/data/blog;
}
}
After installing EFF’s certbot, I can use the magic certbot
command (sudo certbot --nginx
) to provision an LE SSL Cert for hmlhml.com and certbot
automatically rewrites /etc/nginx/sites-enabled/blog
to use the provisioned certificate. After restarting nginx (sudo systemctl restart nginx
), the new site should be up and running
What’s Next?
I few things I could see doing, but I’m not in any rush to do
- Read the nginx logs to get a sense of view counts
- Improve the CSS, especially around code blocks
- Some sort of email list?