Ok, so you may or may not have heard of my Howzit project, so I’ll begin by recapping. “Howzit” is a contraction of “how does it” that allows you to query any project with commands like howzit build or howzit deploy and get documentation, as well as automatically execute the necessary steps for a task. I use it almost every day and it has saved me a crazy amount of time over the years, especially in picking up on projects I haven’t touched for a while.

The heart of the system is a “buildnotes.md” file located in the root of your project. This is a Markdown file where you describe each topic, e.g. Deploy, listing out any pertinent info. Just stop and think “if I come back to this a year from now, what would I need to know?” You can include “directives” that can do things like copy strings to your clipboard or execute code or commands. If you just run howzit TOPIC it will show you your documentation, and if you run howzit -r TOPIC, it will execute any directives in the topic.

Ok, so on to templates. I’ve added a lot of functionality to Howzit over the years, but templates have turned out to be my favorite extension. Templates allow you to store reusable tasks in a single file, and then include all of those tasks with a single line at the top of a build notes file.

Everything discussed in this post can be found in the Howzit wiki, specifically the Templates and Metadata page.

Templates are stored in ~/.config/howzit/templates and are just Markdown files formatted like any buildnotes.md file. Markdown headers for topics, and they can contain text, lists, tables, and, most importantly for my purposes, directives. They’re given a short filename like git.md or swift.md and saved to the aforementioned directory. Then, in any build notes file, you can add a line at the top like:

template: swift, git

All of the tasks in those templates are now automatically included in your build notes without any additional documentation. If you frequently use the same tools and structures for projects of the same kind, this greatly reduces the time it takes to document while minimizing errors.

For example, in many of my templates there’s a topic called “Deploy.” This topic contains the steps necessary to publish a project, specific to the type of project it is. I have one for Swift command line tools, one for Ruby gems, one for Sparkle-based Mac apps, etc. The benefit of always naming the topic “Deploy” is that in any project I can just run howzit -r deploy and deploy that project without looking anything up or remembering multiple steps1.

You can also specify variables in templates, which are then defined in the individual build notes, allowing for reusable code that’s still tailored per-project. For example, for projects that get published to both GitHub and my blog, I have a system that allows me to create a src/_README.md file containing special syntax that creates different output for my Jekyll-based project page and my GitHub README. In the template for such a project, I have variables for the project name, README source, and changelog location. The README source and changelog variables have default values (src/_README.md and CHANGELOG.md), but the blog project name (which is used to locate the file that generates a project page) varies with each project. So the project variable is required and Howzit will let me know if I’ve included that template and not defined that variable.

As an example, here’s my markdown.md template, which has actions for spellchecking using aspell. It allows an optional variable for specifying subdirectories of Markdown files that should be spellchecked, defaulting to just the current folder.

optional: dirs

# Markdown

### Spellcheck

Check spelling of all Markdown files in git repo.

```run Spellcheck all files
#!/bin/bash
for dir in [%dirs:.]; do
    cd "$dir"
    /Users/ttscoff/scripts/spellcheck.bash
    cd -
done
```

### Spellcheck Modified

Check spelling of Markdown files marked as dirty in git.

```run Spellcheck modified files only
#!/usr/bin/env ruby
# Spell check changed Markdown files

staged = `git diff-index --name-status --cached HEAD`.strip.split(/\n/).map {|f| f.sub(/^\s*(A|M)\s*/, '')}
partial = `git status --porcelain --untracked-files=no`.strip.split(/\n/).map {|f| f.sub(/^\s*(A|M)\s*/, '')}
changed = staged.concat(partial).sort.uniq
changed.select! {|f| f =~ /(md|markdown)$/ }

home = ENV['HOME']

changed.each do |file|
  system %(aspell -M --lang=en --dont-backup --home-dir=#{home} --personal=#{home}/aspell.txt check "#{file}")
end
```

Or a simpler one: if the project has a Sublime Text project associated with it, I can just add template: sublime and it will offer me this action:

required: project_file

## Edit Project

@run(subl -p [%project_file].sublime-project)

I just define project_file: binbundle in my build notes, and then running howzit -r edit will open the project in Sublime. I can create one of these for every possible editor/project type, always using “Edit Project” as the topic title, and include the appropriate template in each project. Then howzit -r edit will always open the correct project file in the correct editor.

You can get a list of all of your templates by running howzit --templates. This will show you all templates, what actions they define, and what variables can be (or must be) set for them. You can open any template in your editor by running howzit --edit-template NAME.

Like I said up top, the longer I use Howzit the more times it saves my butt. It’s among the most useful things I’ve built and I think every developer should give it a shot. If you love it, buy me some coffee or become a supporter to ensure future development of this and all of my other projects.

  1. These Deploy topics handle updating changelogs, tagging git releases, pushing changes, compiling distributable versions, updating blog projects and READMEs… way more steps than I’d want to remember when moving between projects.