Automated Documentation Builds with Slate

Automated Documentation Builds with Slate

- 5 mins

:mega: This post is also available on Medium!

I’m currently working with RTrade Technologies, Ltd. and a documentation website was recently set up for one of our APIs. I thought it looked great, and slick, and super nice.

I was told the documentation was generated using a project called Slate, and after taking a look I knew I had to try it out. It’s very pretty.


First step: read some docs. “Getting Started with Slate” seemed like a good place to get started.

Mhm, looking good so far. I’ve got all those things.

Hold up. What? Is this telling me that I can’t just “use” this thing to build documentation as a tool? I need to fork it and change it?

Okay great. Well, I don’t want to do that. I want my documentation to be part of my repository, so it can be versioned alongside our code, and I don’t want to carry around the baggage of an entire repository alongside my documentation. So let’s not do that, and try to hack Slate into a proper doc builder.

Making the Script

mkdir -p docs_build
cd docs_build
if [ ! -d slate ]; then
  git clone [](

To start off, I want my script to grab the repo (I’ll need it one way or another) and chuck it into a temporary directory. I called it docs_build and chucked it into my .gitignore where it belongs.

Next, I’ll go ahead and symlink everything that I’m *supposed *to change in my “fork” from where I want my **actual **documentation to be — I decided to call it docs_src — into the cloned Slate repo.

# in /docs_build

# documentation
ln -fs "$(dirname "$(pwd)")"/docs_src/ \

# CSS variables (colours, etc.)
ln -fs "$(dirname "$(pwd)")"/docs_src/stylesheets/_variables.scss \

# cute logo!
ln -fs "$(dirname "$(pwd)")"/.static/inertia.png \

Note that when creating a symlink with ln -s , you should use the full directory path as your source, or the link could point to something nonexistent. In this case, I opted to use pwd and join it to the file I’m trying to link from.

Next, I’ll need to install Slate’s dependencies:

# in /docs_build

cd slate
bundle install

And hypothetically I should be good to go!

# in /docs_build/slate

# build docs into the /docs directory
bundle exec middleman build --clean --build-dir=../../docs

The build works, and all seems well. Let’s check out live reload:

# in /docs_build/slate

bundle exec middleman server --verbose

If you’re following along, you’ll probably notice that this step tragically does not work properly — editing a file in my /docs_src directory does not trigger a reload.

This probably happens because a symlink doesn’t usually play well with file watchers, and poking around the Middleman repository issues reveals a few (such as this one) that reveals this is likely the problem. Some more digging surfaces a feature that seems to do what I want: add my symlink source directories as a trigger for rebuilds.

The problem is, I need to add this to config.rb , which is in the Slate repository, and I want to maintain my Slate-as-a-doc-builder feature, which means any configuration changes I make must be scripted and perfectly reproducible.

  " :source, path: File.join(root, '../../docs_src')"

if ! grep -q "$TEMPLATE_FILES_WATCH" slate/config.rb ; then
    >> slate/config.rb

Nice! This script checks for if my custom directive is already in Slate’s config.rb , and if not, append it to the end. Now running the Middleman server successfully live-reloads my changes to http://localhost:4567 !

I’m not quite done though — I also want my site to have a favicon. I figured this might be a configuration option in , but it’s not:

Hey, I just realized the author’s name is Robert as well!

Well that’s just great. Time to whip out some sed:


if ! grep -q "<%= favicon_tag 'favicon.ico' %>" "$LAYOUT" ; then
  sed -i '' '/<head>/a\
  <%= favicon_tag '\''favicon\.ico'\'' %>
  ' slate/source/layouts/layout.erb

This checks the layout for the favicon tag, and if it’s not there, insert it right after the <head> tag.

There it is!

Then I had to add the favicon to my list of things to symlink:

ln -fs "$(dirname "$(pwd)")"/.static/favicon.ico \

And it worked! bundle exec middleman server kindly updated my local deployment to show my shiny new favicon:


Finishing Touches

Here’s what the documentation site looks like now:


Feel free to check out the commit or pull request that added all this stuff to Inertia, a UBC Launch Pad project!

Robert Lin

Robert Lin

Enthusiastic eater of lunches. Please feel free to reach out to me at!

rss facebook twitter github youtube tumblr mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora