Turning Slate into a proper documentation builder
No thanks I don’t want to fork your repository. 😶
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.
Beautiful static documentation for your API. Contribute to lord/slate development by creating an account on GitHub.
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
if [ ! -d slate ]; then
git clone https://github.com/lord/slate.git
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/index.html.md \
slate/source/index.html.md# CSS variables (colours, etc.)
ln -fs "$(dirname "$(pwd)")"/docs_src/stylesheets/_variables.scss \
slate/source/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_buildcd slate
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/slatebundle 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
files.watch 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.
"files.watch :source, path: File.join(root, '../../docs_src')"if ! grep -q "$TEMPLATE_FILES_WATCH" slate/config.rb ; then
echo "$TEMPLATE_FILES_WATCH" \
Nice! This script checks for if my custom
files.watch 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
index.html.md , but it’s not:
Well that’s just great. Time to whip out some
LAYOUT="slate/source/layouts/layout.erb"if ! grep -q "<%= favicon_tag 'favicon.ico' %>" "$LAYOUT" ; then
sed -i '' '/<head>/a\
<%= favicon_tag '\''favicon\.ico'\'' %>
This checks the layout for the favicon tag, and if it’s not there, insert it right after the
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:
- I tied everything up together into a tidy (I hope), documented (I think) script.
- I also added a some Makefile targets to run the build script and the live-reload server.
- Of course, writing and building documentation needs documentation as well.
- I forked Slate (and opened a PR upstream) to add some more customization features (mostly in the CSS variables), and am currently using this fork in my script.
- I deployed the documentation to https://inertia.ubclaunchpad.com/
Here’s what the documentation site looks like now: