Being Data Driven

We’re building a static site, but that doesn’t mean we’re going to hard-code everything and construct all the pages by hand - Jekyll has excellent support for driving your content with data. Let’s look at an example:

The data for our site’s footer is in _data/links.yml and looks like this:

- title:       Twitter
  url:         https://twitter.com/uncookedfunk
  fontawesome: fa-twitter

- title:       Facebook
  url:         https://www.facebook.com/rawfunkmaharishi
  fontawesome: fa-facebook-square

- title:       Soundcloud
  url:         https://soundcloud.com/rawfunkmaharishi
  fontawesome: fa-soundcloud

Those titles, URLs and font-awesome icons are exposed as site.data.links[0].title and so on, and we can iterate through them in _includes/footer.html with something like

{% for link in site.data.links %}
  <a href='{{ link.url }}' title='{{ link.title }}'>
    <i class='fa {{ link.fontawesome }}'></i>
    <span class='hidden-xs'> {{ link.title }}</span>
  </a>
{% endfor %}

Building a footer or a navigation bar this way is all very well, but what about entirely data-driven blog posts? Well, those sets of three dashes that we have at the top of each content page are delimiters for Jekyll front matter, where we normally specify things like titles and layouts. However, it’s just YAML, and we can put anything we want in there. Which led me to the idea of

Data-driven gigs

Take a look at this:

---
location:    259 Upper St, London, N1
time:        '20:30'
facebook_id: 1554796168085840
latitude:    51.5461216
longitude:   -0.1032551
---

That’s all the data we need to describe a Raw Funk Maharishi gig (or at least it is for now, it would be trivially easy to support other fields for EventBrite or whatever). Jekyll rummages through our site, looking for any files within _posts/ directories and rendering them as pages - it also parses the filenames to give us a nice /YYYY/MM/DD/title-slug/ URL, as well as page.date and page.title - and because of this bit in _config.yml it defaults to using the gig layout, which has access to those items via page.location, etc:

<dl class='dl-horizontal'>

  <dt>Date<dt>
  <dd>{{ page.date | date_to_long_string }}</dd>

  <dt>Time</dt>
  <dd>{{ page.time }}</dd>

  <dt>Location</dt>
  <dd>{{ page.location }}</dd>

  {% if page.price %}
    <dt>Price</dt>
    <dd>{{ page.price }}</dd>
  {% endif %}

  {% if page.facebook_id %}
    <dt>More info</dt>
    <dd>
      <a href='https://facebook.com/events/{{ page.facebook_id }}/' title='Facebook event'>
        Facebook
      </a>
    </dd>
  {% endif %}

</dl>

and of course page.latitude and page.longitude with which it renders an OSM map.

This data is also exposed as site.categories.gigs - the hash key there is the directory under which our _posts appear, we also have site.categories.blog on this site, as well as all _posts as site.posts - which we can iterate through to construct an archive page.

I have a nagging feeling that this might be a misuse of tools (a gig is not really a blog post), but I’m still feeling my way around Jekyll and this works just fine for now.