Jekyll+CSS Media+PhantomJS+Netlify == Resume w/ Build Process

As a developer I feel like it's important to have an online resume, but I also want to keep an up to date dead tree resume.

Like all developers I loathe doing anything twice; so, I recently put together a build process for my resume, using a few brilliant off the shelf tools.

jekyll

Jekyll is a static site generator. It lets you build static html sites, but with a build process that makes it feel like you're working with something dynamic. For example you can use YAML files to represent your content as data

yaml example image

And then display that data appropriately through a template system

template example image

Jekyll takes the form of a command line utility written in Ruby. You can learn more about it here.

PhantomJS

If you've ever done any NodeJS you've probably come across this. For those who haven't PhantomJS is a headless browser that you can use to render pages on the server. It's a great way to generate PDFs; so, I thought why not use this to create the printable version of my resume. Accomplishments and job experiences are defined in simple to parse data files, Jekyll builds the website from this, and PhantomJS renders it all to PDF.

So here's my simple PhantomJS script

const page = require('webpage').create();

page.viewportSize = {
	width: 767,
	height: 600
};

page.paperSize = {
	format: 'A4',
	orientation: 'portrait',
	border: '0.5in'
};

page.open('http://localhost:4000', function(status) {
	console.log('Status: ' + status);
	if (status === 'success') {
		page.render('resume.pdf');
		phantom.exit();
	}
});

Not a lot to it, but you'll want to be careful with the viewportSize attribute. It determines at what window size the headless browsers renders. To get things looking good on paper can take some tweaking.

Making it look good in print with CSS

In fact, a lot of tweaking but there are several techniques that make it all work.

The first is CSS media tags. You will already want to be making use of the min-width/max-width media tags to control how your page appears on mobile.

media tag example max-width

Next you'll want to pull in print and screen tags. When printing these can hide or show sections or change font sizes and margins. This makes both the PDF render look better as well as any prints made by people viewing the site.
media tag print example

Going further with environment variables

There may be some changes, however, that you really only want applied for the PDF build. Perhaps you want to display your phone number in the PDF but not openly on the site. There could be sections that don't make sense in a standalone print version, but viewers expect to see if they manually print the site

For this make use of Jekyll environment variables. These are accessed in templates through `jekyll.environment'

When I am ready to make a new build of my site, I start jekyll using

JEKYLL_ENV=print-version jekyll serve

Then I run my pdf generation script

phantomjs ./buildScripts/phantomLoader.js && mv ./resume.pdf ./assets/documents/

In my templates I can do fun stuff like

example environment condition

Tying it all together with NPM

Since Node is already being used for PhantomJS, it only makes since to make use of it for our build process as well. You can define a very basic package.js file in the root of the project and then add code to the scripts block to help glue everything together (if you're more of a ruby fan you could do the same thing with rake). For now this is all I need

{
  "name": "resume-pdf-generator",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "jekyll serve",
    "build-css-main": "lessc ./assets/less/default/styles.less ./assets/css/styles.css",
    "build-css-pdf": "lessc ./assets/less/default/styles-pdf.less ./assets/css/styles-pdf.css",
    "build-css": "npm run build-css-main && npm run build-css-pdf",
    "build-resume": "concurrently \"npm run start-pdf-version\" \"npm run output-resume\"",
    "start-pdf-version": "JEKYLL_ENV=print-version jekyll serve",
    "output-resume": "phantomjs ./buildScripts/phantomLoader.js && mv ./resume.pdf ./assets/documents/"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "concurrently": "^3.5.1"
  }
}

Hosting

A shout-out has to go to my hosting provider, Netflify. They raffled off a Nintendo Switch at the Nodevember conference in exchange for trying their free service. I ended up winning the switch! After spending way too much time playing Mario I decided to actually explore their offering which got me interested in using Jekyll again.

They abstract the Jekyll build process by letting you just tie your site to git repo, automatically deploying your site when you push. GitHub pages offers the same service, but currently does not allow you to host SSL enabled sites with a custom domain. I like chriswininger.com but s a regular Defcon attendee I want to SSL all the things; so, in the past I've self hosted Jekyll sites on Digital Ocean. Netlify solves this thanks by leveraging let's encrypt

Final Thoughts

Getting things to look smooth on paper took some doing. Time will tell if it was worth it. I now feel like I need to QA my resume when making formatting changes, checking that it looks good on mobile, desktop, print from web, and PDF; however, it already feels much easier to keep content up to date, and I would have had to test much of that for the sight anyways. If anyone else decides to give this ago I'd love to hear their feedback and what if any issues they run into.

You can reach me on twitter @remembersonly