Baby's First Post
Awww, so cute! It's almost like a real website!
November 17, 2021
13 min read

Hey there! Welcome to my website.

Everything is still in its infancy, and I'll be adding new features and content whenever creativity strikes.

For now, though, I have a brief word of warning: lots of features are missing. Just off the top of my head:

  • it's not bilingual
  • there's no search function nor comments sections
  • none of the links in the menu work
  • the server will surely melt down if any post gets even a modicum of traction

But perfection is an illusion. Worse, the goal of perfection too often takes our eyes off the goal of progress. Put more succinctly: "perfect is the enemy of good."

Hell, even that expression – which packs a lot into six words – is itself an example of the very moral it describes. That is, "perfect is the enemy of good" is a mistranslation of a passage in Voltaire's La Bégeule:

Dans ses écrits, un sage Italien
Dit que le mieux est l'ennemi du bien.

In his writings, a wise Italian
says that the best is the enemy of the good.

And this is a mistranslation of an Italian proverb:

Le meglio è l'inimico del bene

Le mieux est le mortel ennemi du bien

The best is the mortal enemy of the good.

In my case, I've been working on this darn thing for over a year now, and after spending countless hours combing through styling tutorials and pulling my hair out trying to get all these <div>s to appear just so, I've realized that if I keep waiting for perfection before actually posting content, I'm going to be tweaking font sizes in my retirement community.

Yes, 18px Helvetica will do just nicely.

We shouldn't be ashamed of our flaws. We should instead recognize that most of life is a work in progress and be proud of the efforts we make to improve.

Honestly, it'll be fun to display the improvements in real-time. All of the issues that I see here can be improved with time and patience, and describing my process of arriving at solutions might be helpful for other people along the way.

So, you know, let's just start the damn thing already!

What to Write About

There wasn't any subject that leapt to mind for the inaugural post that would get the content train a-rollin'. But, dear reader, one thing is for sure: you should know how much errort has gone into getting this far. I need you to know. Because it's, like, a lot.

"But Alf," you're thinking, "didn't you just get a WordPress or make a geocities?" Clearly no one told you: I'm a masochist. I mean, why pay for a tool that –

Wait, what?



What are you, reading this post on your Palm Pilot? Did you use Alta Vista to get here? Hey, what are your thoughts about this upcoming Y2K bug?


Anyways, like I was saying, why pay for a tool that has 98% of the work done for you when you can pay even more money to sacrifice evenings and weekends troubleshooting what often times turns out to be something like a missing period in a DNS configuration?

In all seriousness though, my career right now is about 50% web development, so getting my hands dirty by manually going through each step of this process seemed like (and has proven to be) a great learning experience. Plus, I'll never be nickle-and-dimed by the service provider for new features; I have direct access to the guts of the site, so I can just make it myself for free.

This isn't even to say that I alone am responsible for all of the work to get this site up and running. Far from it. I have – at every step of the way – benefited from the fruits of a robust, open-source community and a wide range of tutorials written by excellent technology communicators.

Truly, the only reason I am able to send these words to you is because I stand on the shoulders of giants.

Anyways, here's how you, too, can go about...

Building a Website From the Ground Up

Maybe the most crucial component to setting up a website is having a machine on which it can run. I'm no expert in computology, but it seems pretty important. Maybe someday we'll all access distributed websites running on blockchain connected to drones, but until then, you need a box somewhere with your name on it.

Goddamn, these loading screens take forever.

I've been an Linux guy for about 5 years now, so the path of least resistance for me was pretty obvious: an EC2 instance running Ubuntu. There are other options, but Ubuntu has all sort of software support, and – while I don't enjoy adding to the Bezos money pile – AWS is the only cloud system for which I can confidently say that I just barely know my ass from a hole in the ground.

A website isn't much use, however, if all links to the site die every time the server restarts and it gets assigned a new IP. Your friends and family need to read your takes on local politics, and they can't be expected keep asking for the new address every time they want to share your tepid takes with their friends.

No, your only option is to pony up for a static IP address, register a domain name and then connect the two by wading into the maelstrom that is DNS configuration.

At this point, you're almost there. You're dead inside from what feels like years of troubleshooting, but you're almost there. People can enter your human-readable website address and the request will be received by the server.

Unfortunately, much like you can't expect an infant to know what to do with an invitation to a dinner party, you can't yet expect your server to understand why people are sending it these particular ones and zeroes.

You can solve your illiteracy problem with an HTTP server process to field such requests. Some people like Apache, some people like nginx. I went with the latter because I've used it a bit for work already and, quite frankly, because it sounds all cyberpunk ("engine-x").

Just run a few steps to install and configure nginx and, wala, you're online. When people now point their browser to your domain, they will be greeted with a warm "hey I'm a server. I serve things to people who want service."


But you've got bigger plans than this, like showing people how many millilitres of booze you consumed last tuesday and... additional things.

All of this could be managed by nginx and HTML files alone, but you'll (eventually) have a much easier time if you build an application and configure nginx to send all requests its way. Such an application could respond to requests in dynamic ways that would be very difficult and time consuming to configure in nginx.

Enter Flask, which is an ever-growing web framework that makes it dirt-simple to set up a server application (especially if you're, cough, not too shabby at Python). But, seriously, it really is easy. Just look at this tutorial put together by Justin Ellingwood and Kathleen Juell over at DigitalOcean. Even if you've never used any of the tools described therein, you will almost certainly have something workable within an hour.

As a final step, it's considered poor form these days to have unencrypted connections, which is why every website you access starts with "https" rather than "http" and why every modern browser has one of these lock symbols in the address bar.

For your eyes only.

Secure connections aren't strictly necessary if you're not planning on having users do things like send passwords or credit card details. You never know though, maybe someday you'll want a donation button (gotta cover those server costs somehow). Better to nip that in the bud by setting up a free and auto-renewing SSL certificate for your nginx server.

And that's the long and short of it! You're now ready to dive in to deeper concepts like "how do I vertically centre this word," which sends you head-first into the black magic that is cascading style sheets (CSS) and inevitably leads to you recreating the style of 18th century oil paintings using nothing but box-shadows.

What I Like

I started this post on a bit of a low note. To wrap things up, I'd like to go the opposite route and point out some imperfectly good aspects of this site.

Built From Scratch

All of the pieces of this site were designed and implemented by yours truly. From the header to the shadows, what you see now began as a blank slate, with elements added and modified over and over until I liked what I saw.

The benefit of this process (aside from expanding my knowledge of the interplay between CSS and HTML) has been that I can minimize the contents of each file by avoiding all of the crud that comes along with each new tool.

Adapting to Different Device Types

This website it configured to look nice in mobile, tablet and desktop widths. This was achieved through CSS media statements and boatloads of observation of other sites.

Try it out! If you're on your phone: rotate between portrait and landscape. If you're on your computer: drag the side of the browser to make the window thinner.

Beverly Hills Jinja (or: Template-ception)

For the web dev nerds in the house, maybe what I'm most proud of at this point is level of compartmentalization with respect to the various pieces of the site. This was achieved with the Jinja templating tool that comes bundled with Flask.

For an example how such templating works, we don't have to look any further than this very post (babys-first-post.html).

babys-first-post.html extends an article.html template. The latter outlines all of the pieces of a standard article (the title, the description, etc) and how they should be formatted, and the former details what should be in each piece.

We're not done, though. The article.html template itself extends a layout.html template, with this last template describing how the rest of the website should be formatted around the post.

Here's what they look like if they're loaded layer by layer, starting with layout.html:

Now we add article.html. You might have to squint to see it (it just looks like a blank sheet), but you've gotta believe me when I say there's a bunch of stuff hidden in there.

Finally we add in the actual content of the babys-first-post.html post:

This site actually goes even further with its templating niftiness, but that's a tale which deserves its own post.

Layers on Layers

When I first considered how the design of this website should look, I knew I wanted to lean heavy on the idea that any web page is just carefully-designed layers. To that end, click the search symbol up in the top left!

GIF of the slidiness for posterity.

Oooh, would you look at that? There's a whole other layer under there, complete with links to things that don't actually work. What's under that layer though?

Who knows! 😏

(Nothing. There's nothing.)

Dynamic Text and Lazy Image Loading

It can take a bit of time to retrieve text and images from servers. This may lead to a page experiencing something of a formatting whiplash as bits and pieces are shifted around to accommodate the new content.

UX (User eXperience) designs these days are all about minimizing these jarring shifts in format, often times with placeholders. I'm not really a fan of this skeleton approach, partly because it looks so drab, but mostly because it just seems wasteful. The server knows what the request is, why not load as much as your can right away?

For this site's homepage, I went with a sneaky solution for text and another, common solution for images.

When your browser sends a request for the homepage, the server for this site quickly collects the titles and descriptions of recent posts and again works with Jinja templating to bake them into the very first HTML file it sends in response to your request. This avoids a dance between your browser and the server for the placeholder approach, which can take a while on slower connections ("gimme the website structure HTML, ok, got it, now gimme the website content").

The images are a bit trickier; you can't just bake a JPEG into HTML. But if you refresh this site's homepage a couple of times you'll notice that they start off blurry and then quickly come into full-HD focus.

Enhance.... Enhance....

Just a little home-brew lazy image loading I cooked up.

I have a script for processing new posts when they're added to the site. One of this script's main responsibilities is to take the header image and make a teeny-tiny copy. From then on, when any page loads that displays this image, it's this tiny copy that is requested by your browser and displayed with a blur so your don't notice the pixels. A script within the HTML then gets to work requesting the tiny picture's high-def big sister. Once this clearer image finally arrives, the code removes the blurry image and replaces it with the clear image.

If you refresh often enough, you're bound to still see a bit of shifting around, since even small images can't be loaded instantaneously from the server. I've got a plan for this though, so be sure to stay tuned for details on how to implement absolute zero whiplash!

Infinite Scroll

While we're on the topic of home-brew mimicry of nifty features: having a "next page" button is so 2010, so I decided to build infinite scrolling into the homepage and other indices. If you're reading this post a few years from now, its possible that you accessed it by scrolling infinitely. If, however, you're reading this right after I wrote it: tough noogies, you have to wait for newer posts to push this one to the second page.

Keep scrollin' scrollin' scrollin'

Vices and Virtues

Finally, from a content perspective, you may have noticed a widget on the site that displays up-to-date data on what kind of crap I'm putting into my body and in what quantities. It's an ongoing mini-project of mine which I hope will push me to take better care of myself while also being a source of intrigue for anyone with a voyeuristic streak.

Jesus Murphy. What happened here?

I hope to have another soon showing the flip side: all of the good things I'm doing for myself like reading, exercising, and drinking copious amount of water.

Anyways, that's it for now. Thanks for taking a look, and be sure to tell me what you think in the comments secti– oh... right.