HMLHML - Half Moore's Law, Half Murphey's Law

how i write my blog

Written by Grant Powell on 2020-12-26

Why Blog?

I’ve wanted to write a blog for awhile, mostly for these reasons

  1. I’m a self taught software engineer, other people blogging about tech has been invaluable to my learning
  2. 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

Non Goals (for Now)

How hmlhml.com Works

Folder Structure

Directory 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

  1. Read the nginx logs to get a sense of view counts
  2. Improve the CSS, especially around code blocks
  3. Some sort of email list?