BlogGen Lives

November 14, 2015

I posted in March about hoping to post more often to my blog. In what’s probably a bit of self-serving bias, I laid the blame on my tools:

The trouble is friction. The amount of ceremony to post an article or share a file is just too high.

To overcome that friction, I’ve spent some of my free time over the intervening seven and a half months developing my own static blog generator, BlogGen. This was a fun excuse to learn more about css, templates, web fonts, Swift, Ruby, pygments, CentOS, and Nginx.

Requirements

Now that I’m ready to point my DNS records at the new site, revisiting the requirements from my March post seems like an interesting exercise. It’ll serve as a little postmortem on my BlogGen project.

Write in Markdown with Code Syntax Highlighting

I ended up using github flavored markdown as expected. I wrapped a Ruby script around redcarpet and pygments.rb to process markdown input into HTML with nice syntax highlighting of code. I’m also using Gruber’s smartypants.pl to get the quotation marks right. I suppose every site should have a little bit of perl.

One Button Posting

I started BlogGen as a command-line utility, but ended up bundling that code inside a little Mac app. One click in the app generates the site and rsyncs it to my web server. There’s also the option to just generate the site locally — useful for testing changes that go beyond simple posts.

Static Project Pages

Besides just processing markdown, I discovered that I wanted a basic templating engine. Never one to do the rationale thing, rather than adopting an existing system, I built my own for BlogGen. It’s dead simple. Input files for the site have a little key-value definition section at the top, followed by the markdown content. Here’s the start of the file for my About page:

title: About
subtitle: just this guy, you know
slug: about
​^^^
I'm a software developer for the [Omni Group](http://www.omnigroup.com)...

Each sort of page, currently just static pages and posts, have their own template file. The template files for static pages looks like this:

<!DOCTYPE html>
<html>
<head>
    <title>{{title}}—curtclifton.net </title>
    {{include headElementContents}}
</head>
<body>
{{include header}}
<div id="columns">
    <div id="sidebar-column">
        {{include sidebar}}
    </div>
    <div id="main-column">
        <div class="post-header">
            <h1>
                {{title}}
            </h1>
            <div class="subtitle">
                {{subtitle}}
            </div>
        </div>
{{body}}
        <div id="footer">
            <div id="narrow-footer-bits">
                {{include sidebar}}
            </div>
            Copyright © 2010–{{include currentyear}}, Curtis Clifton 
        </div>
    </div>
</div>
</body>
</html>

The input markdown file for every static page on the site is run through that template. BlogGen replaces the stuff in double braces when generating each page.

RSS Feed Generation

My home page shows the five most recent posts. To generate that I use a summary template. That mechanism also generates my RSS feed.

While a regular template just has a single section that it uses to generate each page or post, a summary template has three sections. For example, here’s the summary template that generates my RSS feed:

fileName: feed.xml
​^^^
<item>
  <title>{{title}}</title>
  <description><![CDATA[
{{body}}
  ]]></description>
  <pubDate>{{fullDatestamp}}</pubDate>
  <guid isPermaLink="true">http://www.curtclifton.net/{{filePath}}</guid>
  <link>http://www.curtclifton.net/{{filePath}}</link>
  <author>@curtclifton</author>
</item>
​^^^
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
 <title>curtclifton.net</title>
 <description>Posts and announcements from curtclifton.net</description>
 <link>http://www.curtclifton.net</link>
 <lastBuildDate>{{buildDate}}</lastBuildDate>
{{summary}} 
</channel>
</rss>

The first section gives the summary output file name and, optionally, the number of posts to include in the summary. The second section gives the format for an individual post within the summary and is just like a regular template. The final section gives the format for the summary output as a whole. Within this section the special keyword {{summary}} is replaced with the result of running every post through the preceding section.

Minimum Server Fuss

In March I wrote, “I think I’d like to be able to run code on the server, but I’d also like to have someone make sure all the latest security patches are installed for me.”

I caved a bit on this one. For now, I don’t run any code on the server. I’m running a virtual machine with Digital Ocean configured with CentOS 7 and running Nginx. The server accepts http connections and only vends static files. Apart from http, the server accepts ssh connections, but only with key-based authentication. I’m hopeful that this simplicity will mean maintenance is just a matter of running occasional updates.

For now I’m thrilled with how easy, cheap, and fun it’s been using Digital Ocean. If you decide to check them out, use this link to throw some referal love to my friend Jared who introduced me to Digital Ocean.

Custom Domain

With Digital Ocean, it was just a matter of updating my DNS records with my domain name provider to point at my server. I use Hover and couldn’t be happier.

Was It Worth It?

I’ve had lots of fun on this little side project, so even if I don’t post more often, I think BlogGen was a good use of my time. That said, I have more sense of ownership in my site now and feel like I probably will post more. We’ll see. (Porting my existing content from Square Space, I realized that I have a bad habit of promising future posts and not delivering. I’ve resolved not to do that any more.)

The one significant drawback of my current system is that it doesn’t support posting or editing from iOS. Knowing myself, there’s a chance I’ll decide to port BlogGen to iOS. If I don’t post again here for another seven and a half months, you can guess what I’m doing.