This week was about building and deploying my project website. There were two tasks, learning the version control system, Git, and making the project site. Git was all new to me, but I’ve been writing HTML for about 20 years, so I decided to try something different there: a static site generator.

1. Learning Git

I knew Git would be a steep learning curve, so I got some pre-learning in.

I found the Pro Git book very helpful, but also a few online resources that helped me understand the basics, and configure it to be a little more friendly to use. These are the config settings I found helpful:

Identifying yourself:

git config --global user.name "andrew.sleigh"
git config --global user.email "email@example.com"

You can have the OSX keychain remember your login credentials (I’m not sure this actually applies with the SSH keys methods we’re using.)

git config --global credential.helper osxkeychain

I don’t want to use a command line text editor. But you can set up Git so that, when a text file needs to be edited, it boots you out of the command line to a GUI editor of your choice. I use BBEdit, which comes with command line tools you need to install in order to make use of this feature:

git config --global core.editor "bbedit --wait --resume"

The --wait and --resume flags tell git to wait for you to save he file, and resume the process once you have.

Finally, you can show the whole config file, to see what options you’ve set, with this command:

git config --list

Process for publishing the site to the Fabcloud server

  1. Pull the most recent files from the server in case anything has changed:

git pull origin master

  1. Make my changes, and publish the flat HTML files to my local Git repo:

jekyll build --destination /Users/andrew/Dropbox\ \(Personal\)/Work/Fab\ Academy/Website/Git\ Repo/andrew-sleigh

  1. Check the status of the repo:

git status

  1. Assuming everything’s OK, add the changed files to the repo:

git add --all

  1. Commit those files to the repo:

git commit -a -m 'Commit message'

  1. Push the changed files to the remote repo:

git push origin master

2. Build a personal site on the class archive

I already know HTML and CSS, and I wanted a new challenge. So I thought I’d try making my site using Jekyll, a static site generator. This involves multiple steep learning curves: installing and configuring Jekyll, learning Markdown, and figuring out how to build and serve the static site.

I’ll cover the peculiarities of my setup here…

Working with Jekyll and Git

Jekyll builds the files to a directory, which it can then serve a local copy of the site from. We use Git to upload the website files to the Gitlab server, which hosts the live website.

I want to keep my Git repos and my Jekyll work separate, so when I’m ready to push files to the live site, I build my static HTML files to a different folder using flags on the Jekyll build and serve commands. This command builds to a different folder:

jekyll build --destination /path/to/Git\ Repo/andrew-sleigh 

And this one serves it from that folder:

jekyll serve --destination /path/to/Git\ Repo/andrew-sleigh

(You’ll notice I use human-friendly folder names. I rarely type these. If I want to include a directory path in a command, I just drag that directory in from the Finder.)

Adding a podcast feed

As an added challenge, I’m also trying to record a weekly podcast while I do Fab Academy, and I want to host that podcast on this site. A podcast is basically just an RSS file with some audio attachments (MP3s for each episode) and images (artwork for the episodes).

I found some resources online to help me make my RSS file. I started by following the instructions here, with a few changes to make it work in my context:

1. Download the template RSS file

2. Edit the template RSS file so that it shows only the posts from my podcasts category

I added a podcast category in Jekyll, and put all my podcast episode posts in this category.

I edited this line in my root-level podcast.rss template …

{% for post in site.posts %}

… to restrict the post loop to pull only those posts in the podcast category:

{% for post in site.categories.podcast %}

Then I customised all the metadata to be specific to my podcast. Most of it is pretty straightforward.

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xml:lang="{{ site.lang }}">
<channel>
<atom:link href="{{ site.domain }}{{ site.baseurl }}/podcast.rss" rel="self" type="application/rss+xml" />
<title>Unreliable Devices</title>
<description>{{ site.podcastdescription | xml_escape }}</description>
<link>{{ site.domain }}{{ site.baseurl }}</link>
<language>{{ site.lang }}</language>
<managingEditor>{{ site.email }} ({{ site.author }})</managingEditor>
<webMaster>{{ site.email }} ({{ site.author }})</webMaster>
<copyright>{{ site.time | date: '%Y' }} {{ site.author }}</copyright> 
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
<image>
  <link>{{ site.domain }}{{ site.baseurl }}</link>
  <url>{{ site.domain }}{{ site.baseurl }}/assets/images/unreliable-devices-2-3d-3000px.jpg</url>
  <title>Unreliable Devices</title>
</image>
<itunes:subtitle>{{ site.podcastdescription | xml_escape }}</itunes:subtitle>
<itunes:author>{{ site.author }}</itunes:author>
<itunes:summary>{{ site.podcastsummary | xml_escape }}</itunes:summary>
<itunes:keywords>{{ site.keywords }}</itunes:keywords>
<itunes:owner>
 <itunes:name>{{ site.author }}</itunes:name>
 <itunes:email>{{ site.email }}</itunes:email>
</itunes:owner>
<itunes:image href="{{ site.domain }}{{ site.baseurl }}/assets/images/unreliable-devices-2-3d-3000px.jpg" />
<itunes:category text="Arts">
 <itunes:category text="Design" />
</itunes:category>
<itunes:explicit>no</itunes:explicit>
{% for post in site.categories.podcast %}
 <item>
  <title>{{ post.title | xml_escape }}</title>
  <link>{{ site.domain }}{{ site.baseurl }}{{ post.url }}</link>
  <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
  <description>{{ post.shownotesexcerpt | xml_escape }}</description>
  <guid isPermaLink="true">{{ site.domain }}{{ site.baseurl }}{{ post.url }}</guid>
  <enclosure url="{{ site.domain }}{{ site.baseurl }}{{ post.file }}" length="{{ post.length }}" type="audio/mp3"/>
  <itunes:author>{{ site.author }}</itunes:author>
  <itunes:subtitle>{{ post.title }}</itunes:subtitle>
  <itunes:summary>{{ post.summary | xml_escape }}</itunes:summary>
  <itunes:duration>{{ post.duration }}</itunes:duration>
  <itunes:keywords>{{ post.keywords }}</itunes:keywords>
  <itunes:image href="{{ site.domain }}{{ site.baseurl }}/assets/images/unreliable-devices-2-3d-3000px.jpg" />
  <itunes:explicit>{{ post.explicit }}</itunes:explicit>
  <itunes:block>{{ post.block }}</itunes:block>
 </item>
{% endfor %}
</channel>
</rss>

If you’re trying to do this yourself, the key thing to look for is the use of these variables:

{{ site.domain }}{{ site.baseurl }}

I created these (and added the corresponding values in my _config.yml file to work around the problem of serving the site on two domains with different directory structures. More on this later

3. Edit podcast channel and episode settings

Then I added some per-channel settings to my _config.yml file:

# Podcast Feed Settings
podcastdescription:    "A weekly podcast about how to make almost anything."
subtitle:       "Unreliable Devices"
podcastsummary: "I'm doing Fab Academy in 2018. This is my record of what's happening."
lang:           en
author:         Andrew Sleigh
copyright:      "2018"

And some episode-specific information to the front matter of each article (podcast episode), for example:

layout: post
title: "01 — Firehose of information"
date: 2018-01-24
file: /assets/podcast/ep01.mp3
file_itunes: /assets/podcast/ep01.mp3
categories: podcast
shownotesexcerpt: Firehose of information
summary: In which Fablabs take over the world, and I grow increasingly nervous about the amount of work I've taken on.
duration: "08:23" #audio length in min
length: "6437183" #filesize in byte
explicit: "no" #other option is no
block: "no" #means is shown in itunes
excerpt_separator: <!--more-->

After this, I was pretty much good to go, except for the Jekyll domain snag, which broke all the links in my podcast feed. But that’s a Jekyll problem, not specifically related to serving podcasts, so I’ll deal with that seperately.

4. Verify the feed

Once I did have my feed working pretty well, I used CastFeedValidator to see how it would look to a podcast client, and tidy up any errant metadata.

Fixing the site domain problem

Oh boy, what a headache!

On my local machine, my site is hosted at http://localhost:4000. But on the Fab Academy server, it’s hosted at http://fab.academany.org/2018/labs/fablabbrighton/students/andrew-sleigh/

Moreover, Jekyll, by default, uses absolute URLs for many common links, such as RSS feeds, CSS files, and links between pages. There are 2 consequences.

  1. A site that works locally will not work on a remote server without accounting for the different domains – and vice versa.
  2. Links to images, XML feeds, stylesheets, and between pages will be broken.

There are some solutions presented on this thread. None worked out-of-the-box for me, but I was able to hack a solution from here.

1. Set up a baseurl for the remote server, but override it when testing locally

My _config.yml file has two key variables:

baseurl: "2018/labs/fablabbrighton/students/andrew-sleigh"
domain: "http://fab.academany.org/"

When I push my generated site to the remote server, this ensures any absolute links work fine, such as this one in my podcast.rss template:

<atom:link href="{{ site.domain }}{{ site.baseurl }}/podcast.rss" rel="self" type="application/rss+xml" />

But when I’m testing the site locally, I have to remember to overide that setting with a flag in the Jekyll serve command:

jekyll serve --baseurl ''

And of course, re-serve without the overide when I’m ready to commit the changes to Git, and push to the remote server:

jekyll serve

2. Modify the Jekyll templates to use relative links where possible

I had to hunt through all my posts, and the standard Jekyll templates, to find any absolute links. This included those templates hidden away in the Jekyll Gem. On my computer, these are in /Library/Ruby/Gems/2.3.0/gems. I copied the ones I needed to my site source folder. These are the sort of links I had to hunt down:

Audio embeds:

<audio src="{{ "/assets/podcast/ep0.mp3" | relative_url }}" controls preload></audio>

Links to CSS files:

<link rel="stylesheet" href="{{ "/assets/main.css" | relative_url }}">

Images:

![Initial sketch of my dehydrator]({{ "/assets/images/sketch-dehydrator-1.png" | relative_url }})

Post listings on category pages: <li><a href="{{ post.url | relative_url }}">{{ post.title }}</a> </li>

Phew! So far, that all seems to work …