Draft Blog Posts in Middleman
The RubyLetter site — the one you’re reading right now — is built using the static site generator, Middleman. I really like Middleman because it feels much more fully-featured that Jekyll. However one thing that I missed from Jekyll was the drafts folder. You can put draft blog posts in
_drafts and you’ll see them in development but not in production.
Middleman’s blog plugin doesn’t handle drafts nearly as well. Sure, you can put
published: false in a posts frontmatter and it will be treated as a draft, but published and unpublished posts get jumbled together. It’s difficult to tell what’s published and what isn’t.
Fortunately Middleman provides us everything we need to more-or-less simulate Jekyll’s
The key lies in Middleman’s ability to have multiple blogs per site.
I already had a blog set up in the
/blog path. My
config.rb looked something like this:
activate :blog do |blog| blog.prefix = "blog" blog.name = "blog" blog.layout = "article" blog.tag_template = "/blog/tag.html" end
To add a “drafts” section, I simply created a new blog in the
/draft path, which was only built during development:
configure :development do activate :blog do |blog| blog.prefix = "draft" blog.name = "draft" blog.layout = "article" blog.tag_template = "/draft/tag.html" end end
I then copied my
blog/tag.html templates to the
draft directory and updated their frontmatter to include
blog: draft. This specifies that they should pull the list of posts from the “draft” blog instead of the main blog.
Keeping Drafts Secret
Even though I told Middleman to only generate the “drafts” blog in development, it will still attempt to build and publish the posts as normal non-blog pages.
To prevent this, I needed to tell Middleman to ignore the draft directory altogether during production builds:
configure :build do ignore "/draft/*" end
And just in case the drafts ever do get deployed, I added a line to my robots.txt file to prevent them from being indexed:
User-Agent: * Disallow: /draft
A Draft UI
Finally, I added a navbar link to my new draft blog that is only shown during development:
<% if development? %> <li class="nav-item pull-xs-right"> <a class="nav-link <%= current_page.path.match(/^draft/) ? "active" : "" %>" href="/draft">Draft</a> </li> <% end %>
I’m finally happy with the RubyLetter drafts system! It’s easy to see which posts have been published and which haven’t. It’s easy to find the draft posts in the UI.
Now, time to find something else to gripe about!