Jekyll 201: Beyond Hello World
June 03, 2013
There is plenty of material online showing you how to setup a Jekyll blog, write your first post and add a custom domain. But rarely do these tutorials go past the “Hello World” stage.
So it’s time for Jekyll 201!
I’ve been using Jekyll for blogs, meetup groups, prototyping, and microsites for nearly 3 years so I wanted to share some more advanced techniques that aren’t covered in the docs.
Partials
The basics of partials (includes
in Jekyll parlance) are covered in the
docs: http://jekyllrb.com/docs/templates/#includes
If you are coming from a traditional web development background, you might want to know how to pass in data to a partial. Maybe you have some book recommendations in your sidebar, like so:
<ul id="book-recommendations">
<li class="recommendation">
<img src="/img/pragmatic-programmer.png" />
<a href="http://pragprog.com">Pragmatic Programmer</a>
<span>My favorite book about programming pragmatically</span>
</li>
<li class="recommendation">
<img src="/img/getting-real.png" />
<a href="http://gettingreal.37signals.com">Getting Real</a>
<span>A book about Getting Real and stuff...</span>
</li>
</ul>
You can make a partial (e.g. _includes/recommendation.html
) so you aren’t
copy-pasting HTML code:
And then use it like so:
We can re-use the HTML template but this is still not so great. Liquid doesn’t have the ability to pass in a hash of local objects (like in Rails), instead we have to rely on essentially global variables.
Abusing _config.yml
A better way to handle the above case of book recommendations is to store the
underlying data in _config.yml
. This file is typically used to store configuration
options for Jekyll, but any extra YAML data you put in _config.yml
will be
accessible in templates via the site
variable.
So the _config.yml
would look like this:
# General Jekyll Config
auto: true
pygments: true
exclude: [".gitignore", "readme.md", "Gemfile", "Gemfile.lock"]
# Book recommendations
recommendations:
- img_url: /img/pragmatic-programmer.png
url: http://pragprog.com
name: Pragmatic Programmer
summary: |
My favorite book about programming pragmatically
- img_url: /img/getting-real.png
url: http://gettingreal.37signals.com
name: Getting Real
summary: |
A book about Getting Real and stuff...
Caveats: changes to this file are not picked up when running Jekyll locally with
the --auto
flag, so you need to regenerate the site manually for changes to
take effect (several hours of my life I will never get back).
Make sure all of your data is valid YAML (here is a good linter).
Then in your template, you can loop over all the book recommendations.
And update the partial to use properties on recommendation
…
Much better! And now, when you want to add a new book, just add it to the list
in _config.yml
and it will get rendered when you regenerate the site.
I’ve used this technique several times with success, here are a few examples:
- Indy Startup Lab: listing the members and projects, repo here
- Let’s Work Happier: microsite with app directory, repo here
Adding extra fields to posts
Pages have some default attributes that you can set in the Front-matter; these include the basics like permalink, title, categories, and tags.
But you are not limited to just these fields. You can add any arbitrary data to
the Front-matter (it is just a block of YAML after all) and they will be exposed
on the page
variable.
Let’s say you write reviews on your blog sometimes and use Amazon Affiliates. Per the affiliate guidelines, you need a disclaimer on your post stating that you are participating in the program or the FCC will get mad.
You could copy and paste it to the bottom of each Markdown post — but a better way would be to set a custom attribute in the Front Matter.
---
layout: post
title: "My Favorite Gadgets Reviewed"
disclaimer: true
---
By adding disclaimer
to the Front-matter, we can use page.disclaimer
in the
post
layout to display our affiliate text at the bottom of the post when
necessary.
This technique is pretty powerful, here a few other ideas you can use it for:
- Author attribution: useful for multiple author blogs/sites
- Enable/disable Disqus/LiveFyre comments on a per-post basis
- Add summary, subtitles, per-post header images
- Display a banner for your new startup at the bottom of posts
Ghetto Asset Pipeline
A little trick I picked up from the DevelopmentSeed blog — you can use
includes
to concatenate your CSS files.
Move your CSS files into the _includes
folder (I like to put them in a css
sub-folder). Then make an all.css
file with an empty Front Matter, here is the
one from the blog you are currently reading.
---
---
{% include css/font-awesome.css %}
{% include css/base.css %}
{% include css/skeleton.css %}
{% include css/screen.css %}
{% include css/layout.css %}
{% include css/syntax.css %}
Voilà! Six asset requests down to one!
Custom Plugins
The new Jekyll docs have a great section on writing plugins with several examples so I won’t dive into it here.
Be warned — you cannot use custom plugins with GitHub pages. I am of the opinion that GitHub pages is a huge benefit to using Jekyll, so be careful about relying on plugins.
Often times you can reproduce the functionality with Javascript or a Modular Component (see below). Personally, whenever I reach for a custom plugin I step back and evaluate whether I really need the functionality at all — usually the answer is no.
Building Modular Components
Static sites, by design, are very limited. In a world where you can build an entire business on a WordPress blog, Jekyll seems very simplistic.
For the most part, I think this is good — I believe in putting the emphasis back on content. But there are times when you miss some of the conveniences of heavier content platforms.
You can add some of this functionality back by using Modular Components. The basic concept is to write smaller services that your blog can interact with. By offloading the backend work to other apps you can get around some of the limits of a static site.
The most discussed example is using a 3rd party comment system — so I will skip that. Two other use cases that I think are more interesting are an email form and a web-based post editor.
For the email form, I created a simple Ruby app that accepts cross-domain POSTs and sends emails to the officer list for a local meetup. The Jekyll site just serves up the form with the action pointing to the mailer app. Not perfect, but certainly better than setting up a whole CMS.
Prose is an app that allows you to edit and create posts on GitHub pages with a web interface by connecting to the GitHub API. I personally still stick with the command line and SublimeText for writing my posts, but those of you that miss having a WYSIWYG web editor for your content should check out Prose.
Are there more Jekyll topics you want to see covered? Hit me up on Twitter.