Building a Website with Jekyll
The tools, software, and services I use to build and host this site.
Updated December 2015

Around the end of my sophomore year of university, I built my first website. I thought it would be a good way to familiarize myself with the basics of web development and would make a good landing page for potential employers.

I put it together in a few weeks using the Twitter Bootstrap and some hopelessly out-of-date online tutorials. Needless to say, it was bad; it was ugly; it wasn’t responsive; and it was essentially just a static page with few paragraphs about myself and links to my résumé.

When it came time to apply for my third and final co-op in the Spring of 2014, the site had gotten to the point where it was more of an embarrassment than an example of my development skills. I decided to rebuild it from the ground up. This time instead of just building a landing page or web version of my CV, I wanted to make it something I could use to publish my own content.

The site has been changed and restructure a number of times since the initial redesign, but I’ve tried to keep this post as up-to-date as possible.

photo of computer

Inspiration

I realize that a website for self-publishing content is not a novel idea; there are countless other sites and services that provide this exact functionality. I could have used SquareSpace or Tumblr to write blog posts and Flickr for my photo galleries or any of these services’ many alternatives. But I felt that building something on my own would make me a lot more motivated to produce new content. If I built the site myself, it could look, function, and operate exactly how I wanted it to.

I began by exploring the blogs and personal websites of people in the software industry. I admired the minimalism of blogs like John Gruber’s Daring Fireball, but I loved the media-rich design of the then-newly-popular Medium.

Eventually, I discovered the Twitter designer Paul Stamatiou’s website, and felt that its format captured exactly the kind of content I wanted to produce. His site has a section for blog posts as well as one for photo journals of his travels; I modeled my own site’s functionality off of this same two-section pattern.

Tools

One of the downsides of having such an immense number of frameworks and tools available to the modern web developer is that the sheer volume of options can make it hard to choose the best tool to solve a problem. Often times there is no right answer; in fact, most of the time, a number of different tools can be used to solve any given problem. The most important thing is to once a tool been chosen, that it is used correctly and efficiently.

I use a variety of different tools on each level of my site’s architecture, but there are a few that really lay its foundation. First and foremost is Jekyll. Jekyll is a static site generator written in Ruby; it generates the HTML for my website from blog posts and site pages written in easy-to-write markdown. Building the site prior to deployment means that I virtually never have to worry about operational load. The entire site is simply a collection of static HTML documents. I develop and build the site with the incredibly useful task-runner GruntJS and a litany of its plugins.

Backend

A lot of the more technical information about how to install the site’s dependencies and get a development environment up and running can be found in the project’s Github README, though if you’re trying to build a website using mine as a starting point, you might get a bit lost as it has a reasonably specific implementation that isn’t entirely shared.

Jekyll

Jekyll is really good at creating a barebones website from a collection of markdown in no time flat; this is originally all that the project set out to do. Over time, however, its users’ demands evolved, and greater functionality came by way of ruby plugins mixed into plain text.

I love Jekyll for its simplicity and how easy it makes it to generate new content, but sometimes it falls short. It’s templating system Liquid is dreadfully bad, and at times I cringe at the code required to write the simplest of tasks.

For example to add one to a variable you need to write: assign var = var | plus: 1. It’s getting better and the 3.0 release was a big step forward but it still has a way to go before it reaches the right balance of usability and versatility.

Web Server

When I first started building this website, I hosted its files using Sinatra - a lightweight ruby-based web framework. Because my site is essentially just static files, all I ever really used Sinatra for was convoluted redirect-logic. When I redesigned the site in Fall of 2015, I got rid of Sinatra altogether and moved to hosting my website entirely in AWS.

Frontend

Frontend frameworks and boilerplate like Twitter Bootstrap and Foundation are excellent tools for bringing up a decent-looking site quickly, but they abstract away all the most diffiult-to-understand parts of CSS, and so ubiquitous on the web that the design patterns employed feel tired and overused. I wanted to learn CSS myself so, I’ve written almost all of my site’s styling and JavaScript from scratch. I use npm to manage the sites various third-party JS libraries.

Stylesheets

Writing good CSS is one of the most underappreciated skills in the software industry and it was something I had been horrendous at. I’m not claiming that my current CSS structure and organization is great by any means, but I’ve done my best to modularize it and structure it in a logical way. I’ve loosely based its organization on the principles of SMACCS. I generate my CSS using SASS and its indispensable companion Compass.

JavaScript

My JavaScript mostly handles user experience elements and smalls amounts of interface. The JS I’ve written is mostly a collection of jQuery modules (though, lately, I’ve been making an effort to write everything in vanilla JS).

I do use a couple of JS plugins which I’ve modified to accommodate my own site’s structure; my photo gallery implementation is based off of Terry Mun’s Fluidbox in tandem with unveil.js, and my lightbox implementation uses PhotoSwipe.

Creating Content

The main driver for my decision to use Jekyll is the ease at which it allows me to create content. Pages and sites are written in simple markdown interwoven with Jekyll’s plugin/tag syntax.

Markdown

My posts usually start on my Phone or iPad in my favorite note-taking app Simple Note. Once the content has been outlined, I flesh it out and add images on my computer.

Media

One of the most useful parts of Jekyll is the ability to write custom plugins which can be embedded into markdown posts and generated as HTML. I use plugins to generate everything in my posts that isn’t text.

Photos

When I’m finished editing photos in Lightroom, I don’t need to waste time generating a bunch of different sizes and shapes, instead simply export them all as reasonably large, minimally compressed JPEGS, and use a very heavily modified version of the jekyll-image-tag to generate custom-sized, web-friendly images.

{% image default-preset page/image.jpg %}
Source Markdown
src/photo/page/
└── image.jpg
Source File System
<figure class="some-class">
  <img src="image-1000x750-sRcMd5" data-ratio="2" data-width="1000" data-height="500" data-src-small="src="image-500x375-sRcMd5" data-src-large="src="image-1500x1125-sRcMd5.jpg"/>
</figure>
Generated HTML
static/photo/page/
├── image-1000x750-sRcMd5.jpg
├── image-1500x1125-sRcMd5.jpg
└── image-500x375-sRcMd5.jpg
Generated File System
Videos

Hand-generating videos in different sizes and formats is an equally, if not more, painful process than managing image generation by hand and eventually it drove me to write a plugin for generating web-friendly videos of any size from source videos in any format.

{% video default-preset page/video.avi %}
Source Markdown
src/video/page/
└── video.avi
Source File System
<figure class="media">
  <video data-ratio="1.77" data-width="900" data-height="506" poster="/static/video/page/video-900x506-sRcTiMeStAmP.jpg">
    <source src="/static/video/page/video-900x506-sRcTiMeStAmP.mp4" type="video/mp4">
    <source src="/static/video/page/video-900x506-sRcTiMeStAmP.webm" type="video/webm">
  </video>
</figure>
Generated HTML
static/video/page/
├── video-900x506-sRcTiMeStAmP.jpg
├── video-900x506-sRcTiMeStAmP.mp4
└── video-900x506-sRcTiMeStAmP.webm
Generated File System

Hosting

Since the site’s inception I’ve gone through a number of different services and patterns for hosting its content. I’m happy to say however, that now, the site’s HTML, images, videos, and other assets are all hosted using Amazon’s Simple Storage Service and its content-distribution networking Cloudfront. I’ve written an entire post about how I host my static assets and images. Using AWS keeps deployments simple and fast, latency low and very very cheap.