Advance Jekyll
This is the final part in a three part series on static site generators.
- Why Static Site Generators
- Getting Starting With Jekyll
- Advance Jekyll (You are here)
In the previous post I talked about Jekyll, a popular static site generator written in Ruby. In fact, it’s what this site has been using for a while. During that time, I’ve picked up some tips and tricks that I want to share with you today.
The things you find in here are not best practices, absolute truths, or even the best way to do things. With development, there’s a thousand different ways to do something, these just happen to be what I found works.
In This Post
- Deploy To S3
- Manage Your Dependencies
- Stop Excluding Files
- Plugins
- Custom Liquid Tags
- Custom Filters
- Assets
- Testing
- Automated Deployments
- Wrapping Up
Deploy To S3
GitHub Pages offers a free solution for hosting a Jekyll site on a platform you probably already use. This works wonderfully for the majority of sites out there. However, because it is a hosted solution, there’s limitations to it. You can’t run custom plugins and the build process has to be completely done through Jekyll. The power of Jekyll is really unlocked when you deploy to another platform that you have control over.
Because Jekyll outputs static files, the options for where you can deploy your site are endless. You could manually upload the files to a web server you own or even automate that process with a tool like rsync.
This site is hosted on Amazon S3. It was a product I was already using and I don’t have to worry about security, updates, or any of the other things you have to with a normal web server. They have static website hosting built in, but it can be a bit confusing to get setup. Instead, I recommend using a tool called s3_website. Not only does it manage S3 static hosting configuration, it can upload your site for you (and only the files that changed), use AWS CloudFront to distribute your website, manage HTTP cache control and gzipping, and much more. Obviously you don’t want to commit your AWS access or secret keys, so either keep the file local, or commit an example copy of it without those values.
Manage Your Dependencies
As you dive deeper into customizing and streamlining your Jekyll site, you’ll find yourself using lots of different tools. Using a dependency management tool like Bundler can help easy that and provide consistency between any different environments you may be using.
To get you started, here is a starting Gemfile
for Jekyll.
You can also target a specific version of Jekyll.
Make sure you also commit your Gemfile.lock
file to manage specific versions of dependencies.
Stop Excluding Files
We’ve added two more files to our directory that we probably don’t want to be a part of our final site. If we add more tools like Gulp or Yarn, we would need to add more files to exclude from our site. Jekyll allows you to define the source of your site. By default this is the current directory (.
), we can change that with the source
option. Either on the command line or even better, our _config.yml
file.
This directory can contain only files that Jekyll uses to generate the site and you won’t have to worry about extra files getting into your build.
Plugins
Now that we have all the boring stuff out of the way, we can start getting to the cool parts. Arguably one of the most powerful features of Jekyll is it’s plugin system. There are plugins out there to generate sitemaps, RSS feeds, add SEO tags, and more. There’s even support for some plugins on GitHub Pages.
There are a couple different ways to install plugins in Jekyll. The first is to list it in your _config.yml
.
If you’re using Bundler, you can use the jekyll_plugins
group and those will automatically be registered with Jekyll.
You can find out all about Jekyll plugins at their documentation.
Custom Liquid Tags
Liquid is a pretty powerful templating language. With Jekyll we can build on top of that and add custom tags. This is done by as a Jekyll plugin, all we need is a little Ruby.
As an example, I want a tag that strips out all extra whitespace. To do this, I create a file called _plugins/spaceless.rb
.
Now we have access to a spaceless
tag in our site.
Custom Filters
You can also add Liquid filters. Filters are Ruby modules that export all their methods to Liquid.
Filters are applied via pipe ({{ profile.jpg | asset_url }}
).
Assets
I remember when Jekyll didn’t support Sass or CoffeeScript out of the box, luckily that’s all changed and adding Sass to your site is easy. Concatenating CSS/JS, optimizing images, and adding in third-party assets aren’t as easy. If Jekyll out of the box works for you, that’s great. If you need something a little bit more advance, read on. I’m going to go over two different options. Gulp or Jekyll Assets.
Gulp
Gulp is a build system for JavaScript. I’ve personally used it for other projects and I love it. I’m not a front-end developer by any means, but it’s really easy to use. Unfortunately, there’s a million different ways to configure your build. If you’re looking for a place to start, I would check out generator-jekyllized.
I was never able to get a build pipeline that I liked in Gulp, so I don’t have much insight here, but there are tons of sites out there that have done this.
Jekyll Assets
I was never able to get a build pipeline in Gulp that I liked, so I decided to go with a pure Ruby option of Jekyll 3 Assets. If you’re not comfortable with NodeJS or Gulp, but need something better than what Jekyll provides out of the box, this might be a good solution for you. Jekyll Assets is an asset pipeline for Jekyll 3 using Sprockets, the same system Rails uses. With the support for Sprockets, I was able to switch over to Jekyll Assets from my old Gulp build in about 10 minutes.
Testing
We have this badass site. It builds all our assets for us, we’ve customized it with some third-party plugins and even a few of our own. It’s perfect, how do we make sure it stays that way? We can test it!
What can we test? First we can test that everything with Jekyll is ok. Let’s run the doctor
command.
$ jekyll doctor
We should also test that all the links in our site are going to resolve to a working page. To do this, we use the html-proofer gem. This will scan all links in HTML pages and make sure they return a real page. I’ve had this catch links that were broken on old posts.
$ jekyll build
$ htmlproof [site-dest]
For most sites, this is probably sufficient. Let’s say you have a site that uses a lot of custom plugins or logic in your templates that you want to test. We could use a tool like Selenium or a lighter tool like PhantomJS. I used CasperJS for this site. (see below) It offers some really useful tools specific for testing. Here is an example test:
You can check out the full test for this site on GitHub.
Additionally you could do some CSS regression testing using a tool like BackstopJS, Wraith, or PhantomCSS.
Update 10/25/17: With ChromeDriver now supporting headless mode, I switched to Nightwatch.js. The documentation feels lacking at points, but it’s very powerful and easier than Casper to write tests.
Automated Deployments
One of the things I really missed about GitHub Pages was the ability to push a change to my site and have it automatically built. With s3_website, I need to remember to build and deploy my site. If I’m away from home, I can’t make a change with GitHub’s interface and have it automatically build.
Or can I?
With a tool such as TravisCI it is possible to have automatic deploys on push. First let’s create a .travis.yml
that just builds and tests our site.
Here we’re using a Ruby 2.1 Travis container to build our site. I’ve set a custom install script that installs gems to vendor
and then caches that directory to speed up the installation process. For our test script, we build the site and then run html-proofer against the build.
Travis has an after_script
option that will run after a successful build. We don’t want to expose our AWS access and secret key, so we need to add them as encrypted variables. Then change our s3_website.yml
to load those from the environment instead.
Finally, we only want to run this on the master branch. Travis gives an option to only run on certain branches.
If we make a change to our site using GitHub’s interface, it should automatically build and push our site. Huzzah!
Wrapping Up
This is only scratching the surface of what Jekyll and static site builders are capable of. If you have any useful tips or tricks you’ve learned with Jekyll, please share them in the comments.