On Staticness

For almost 7 years, now I’ve had a desktop at home, running, serving (among many things) my personal blog. Doing so is how I learned much of what I now know about programming and system administration. It gave me a reason to learn HTML, then PHP, then finally Haskell. It taught me Postgres, Apache, then lighttpd, then nginx. Without maintaining this site myself, on my own desktop, I doubt I would’ve been sucked into these things and I may not have ended up where I am today.

However, I’m now a happily employed Developer and I do these things all day on other people’s machines and sites. Don’t get me wrong, I enjoy it all very much, but the educational value of maintaining my personal blog as a locally-hosted web-app is just not there any more. With that value gone, things like power outages, harddrive failures, Comcast, etc which bring my site down become unacceptable. It’s too easy to have something which requires almost no maintenance while still giving me the control and work-flow I want.

I realize I could’ve moved my site as-is to a VPS and no longer been at the whim of Comcast and NSTAR, but that wouldn’t decrease the maintenance burden enough. Contrast pretty much any typical web-app ecosystem with…

The services now required to host my blog:


The configuration required to host my blog:

$ wc -l < /etc/nginx/nginx.conf

Adding a new post:

$ cat > posts/2013-09-21-awesome_post.md <<EOF
title: Awesome Post
tags: some, tags

Pretty *awesome*.



$ jekyll build && rsync -a -e ssh _site/ pbrisbin.com:/srv/http/site/


$ tar czf ~/site.backup _site


Unfortunately, Comments aren’t easy to do with a static site (at least not without something like Disqus, but meh). To all those that have commented on this site in the past, I apologize. That feature is just not worth maintaining a dynamic blog-as-web-app.

When considering this choice, I discovered that the comments on this site fell into one of three categories:

  1. Hey, nice post!
  2. Hey, here’s a correction
  3. Hey, here’s something additional about this topic

These are all useful things, but there’s never any real discussion going on between commenters; it’s all just notes to me. So I’ve decided to let these come in as emails. My hope is that folks who might’ve commented are OK sending it in an email. The address is in the footer pretty much where you’d expected a Comments section to be. I’ll make sure that any corrections or additional info sent via email will make it back into the main content of the post.


At some point during this process, I realized that I simply can’t convert my post markdown to html without pandoc. Every single markdown implementation I’ve found gets the following wrong:

<div class="something">
I want this content to **also** be parsed as markdown.

Pandoc does it right. Everything else puts the literal text inside the div. This breaks all my posts horribly because I’ll frequently do something like:

This is in a div with class="well", and the content inside is still markdown.

I had assumed that to get pandoc support I’d have to use Hakyll, but (at least from the docs) it seemed to be missing tags and next/previous link support. It appears extensible enough that I might code that in custom, but again, I’m trying to decrease overall effort here. Jekyll, on the other hand, had those features already and let me use pandoc easily by dropping a small ruby file in _plugins.

Update: I did eventually move this blog to Hakyll.

I figure if I want to be a Haskell evangelist, I really shouldn’t be using a Ruby site generator when such a good Haskell option exists. Also, tags are now supported and adding next/previous links myself wasn’t very difficult.

With the conversion complete, I was able to shut down a bunch of services on my desktop and even cancel a dynamic DNS account. At $5/month, the Digital Ocean VPS is a steal. The site’s faster, more reliable, easier to deploy, and even got a small facelift.

Hopefully the loss of Comments doesn’t upset any readers. I love email, so please send those comments to me at pbrisbin dot com.

21 Sep 2013, tagged with meta, system, jekyll, pandoc

Faster Mail

I hear and see a lot of passing complaints about dealing with a large amount of mail. I myself subscribe to a few mailing lists which get quite a bit of traffic and these are usually the first to be ignored when I get behind. Once a backlog of unread mail piles up it can be hard to get any traction. The sad part is I enjoy that content, so I definitely don’t want to be missing out just because I occasionally can’t keep up.

As readers of this site might know, I use mutt to interact with my mail. Well, I recently implemented some subtle changes which have allowed me to get through this mail more quickly and not stop altogether just because I get a bit behind.

I thought it might be useful to outline these tips for others. Obviously, it assumes a similar setup as mine and some of these might not translate very well.

Choose what you care about

I used to sync everything down from Gmail into the local Maildir assuming I’d want the option to search it. Turns out, I almost never do, instead these mailboxes just clutter up any view of “what’s new” that mutt is trying to give me.

Assuming you’re using my python helper for offlineimap, you can very easily exclude some of the noise from being synced:


pythonfile = ~/.offlineimap.py

[Repository Gmail-Remote]
folderfilter = exclude([ '[Gmail]/All Mail'
                       , '[Gmail]/Important'
                       , '[Gmail]/Spam'
                       , '[Gmail]/Starred'
                       , 'Priority'

Yes, I exclude the “Important” stuff. How ironical.

You can also tell offlineimap to write a mailboxes file for mutt to source. This way, mutt will stay up to date on exactly what folders you care about and you only need to declare what you (don’t) care about in one place.


enabled = yes
filename = ~/.mutt/mailboxes
header = "mailboxes "
peritem = "+%(accountname)s/%(foldername)s"
sep = " "
footer = "\n"


source ~/.mutt/mailboxes

Mailboxes that matter

Now that you’ve got mutt aware only of mailboxes that matter, you’ll find that pressing c to change mailboxes automatically becomes more useful.

Mutt auto-fills the Change-to prompt with the mailbox which last received new mail. Assuming you’re actually keeping things clean (which we’ll get to soon), that’s the mailbox you should be looking at.

c Enter, Deal with it. c Enter, Deal with it…

When you find an empty prompt, you’re done.

Don’t leave until you deal

So now that you can move quickly through any and all mailboxes that require your attention, how do you actually deal with it?

First, I setup my mailbox to show all threads as collapsed, with a keybind to toggle them open:


folder-hook * "exec collapse-all"

macro index ,v "<collapse-thread>" "collapse/uncollapse thread"
macro index ,V "<collapse-all>"    "collapse/uncollapse all threads"

I also color threads with new mails (and the new mails themselves):

# threads containing new messages
uncolor index "~(~N)"
  color index brightblue default "~(~N)"

# new messages themselves
uncolor index "~N"
  color index brightyellow default "~N"

Now I have a good overview (at the mailbox level) of what I’m dealing with. From there I can expand-read what I want, mark whole threads as read, or mark the whole mailbox as read.

Assuming the majority of threads are closed in this mailbox, I use the following to mark-as-read only open threads:

macro index ,r \
  "<tag-pattern>all<return><tag-prefix><clear-flag>N<untag-pattern>all<return>" \
  "mark all as read"

This macro is technically mark all read, but in actuality only open threads are affected. It also catches any one-message threads as they’re by-definition open as well. I expect and rely on this behavior, but I understand if it’s not for everyone.

In the cases that I do want to mark the whole mailbox read including any closed threads, I just use this second macro to open everything before running the above, then close it up again after:

macro index ,R "<collapse-all>,r<collapse-all>" "mark all as read (collapsed)"

That just about sums it up. The best part, if I’m feeling particularly unreachable, is to blindly do the following:

c Enter , R c Enter , R… Until it’s All Gone.

30 May 2013, tagged with mutt, email, offlineimap, system