Styling a Middleman Blog with the Bourbon Suite: Revisited

It’s been a while since we first released our blog post about setting up a Middleman Blog with the Bourbon suite and some things have changed since 2014. Middleman is one of our favorite static site generators and Bourbon is an open-source, lightweight scss suite for styling websites. There’s a new release of Middleman, and we’re on new versions of Bourbon and Neat as well. Let’s revisit how we can get a blog up and running with Middleman considering all these updates and with some new shortcuts along the way.

Introducing: The Middleman Template

Here at thoughtbot, we use Middleman sites for everything from prototyping to landing pages to our own personal sites. To make our lives easier, we created the Middleman Template configured with some of our most commonly used features and tools like SassC, Bourbon, Hound, and a handy SVG view helper. It’s also ready to to deploy to Netlify if that’s your jam. There’s a few other goodies in there, but I’m not your mom and it’s up to you if you want to take advantage of them.

Using this template as a base, we’ll go through how to add blogging functionality, using the Bourbon suite to set up some basic styles, and how to deploy to GitHub Pages.

Set up

First we’ll fork the repo. Head on over to the Middleman Template repo and click “Fork”. This will make a copy of the repo and allow us to keep our repo in sync with any updates from the original thoughtbot repo.

Navigate to your fork of the repo and clone or download the fork locally. After you’ve cloned your fork, you’ll want to configure git to sync your fork with the original thoughtbot repo.

git remote -v will show you the current configured remote repository which should be:

origin https://github.com/[YOUR_USERNAME]/[YOUR_FORK].git (fetch)
origin https://github.com/[YOUR_USERNAME]/[YOUR_FORK].git (push)

Type git remote add upstream then paste the url of the thoughtbot template which should look like this:

https://github.com/thoughtbot/middleman-template.git

and hit Enter.

Double check the upstream repo was added by typing git remote -v one more time. You should see the URL of the fork as the origin and the URL of the original thoughtbot repo as the upstream.

You could also clone the thoughtbot/middleman-template repo directly but make sure to set up a new remote on your own GitHub account so you don’t accidentally push things to the wrong repo.

Middleman File Structure

Middleman sets you up with a main source/ directory. This is where all your stylesheets, assets, layouts and content will live. You’ll likely spend some time in the config.rb and Gemfile files as well. This is where you’ll configure settings for your site and add gems, respectively.

The thoughtbot template gives you some bonus files. Check out the README for more info on what you get out of the box.

Adding the middleman-blog gem

Usually, when you set up a Middleman blog from scratch, you can initialize it with the blog template] built in, but we’ll do it manually.

Head over to your Gemfile and add:

gem "middleman-blog" , "~> 4.0"

In your config.rb add:

activate :blog do |blog|
  # set options on blog
end

Then, run bundle install in your terminal.

Adding some bloggy files

Normally, when you initialize a Middleman site with the blog template from scratch, default index.html, tag.html, calendar.html and feed.xml files are generated. You could run middleman init --template=blog or we can add just the ones we need ourselves. If you decide to run the middleman init —template=blog command, it will rewrite our already existing Gemfiles and config so I prefer to add my own files adapted from the sample ones in the Middleman-Blog repo.

Set up the index

Let’s display all of our articles on the index page. We already have an index file from the template so hop into index.html.erb , delete the h1 tag in there and add:

<% blog.articles.each do |article| %>
  <div class="post-block">
    <h4><%= article.date.strftime('%b %e %Y') %></h4>
    <h2><%= link_to article.title, article %> </h2>
    <p><%= article.body %></p>
    <%= link_to 'Read more…', article %>
  </div>
<% end %>

This should take all of our posts and display their title, date, content and a link to the article.

Looks like there’s nothing showing up in our browser yet! That’s because we have no posts. Let’s create our first blog post.

Adding Posts

You can configure Middleman to use any format for blog posts, but we like to use Markdown. Add a new file and call it [current year]-[current-month]-[current-date]-your-title-here.html.markdown. This is the default filename structure that Middleman uses. For example:

2017-05-03-welcome-to-my-blog.html.markdown

Middleman posts also use frontmatter to generate meta data about a post. Open up the file you just made in your text editor of choice and add the following bit of frontmatter:

---
title: Aliens are cool
date: 2017-05-03
tags: pizza, opinion
---

Right here we’ve added a title, date and tags to our post. Pro-tip: make sure the date in your frontmatter matches the date you set in your article title.

Add whatever content you’d like your first post to be. I’m going to add some Tina Ipsum and call it good for now.

To see our blog post show up, we need to restart our server. After that, we should see our post appear on the home page.

Tags

It’s helpful to let your readers easily search through your posts by tag. You can do this by adding a page that will display all posts tagged with a specific name. Let’s add one now.

To see this in action, let’s create another new post and call it something like 2017-05-04-my-second-blog-post.html.markdown

Add your frontmatter:

---
title: Space is cool
date: 2017-05-04
tags: space, nasa
---

Add some text to your post and restart your server and you should see the second post appear.

Create a new file in source called tag.html.erb.

In that file, add:

<h1>Articles tagged with <em><%= tagname %></em></h1>

<ul>
  <% blog.articles.each do |article, i| %>
     <li>
      <h2><%= link_to article.title, article %> </h2>
    </li>
  <% end %>
</ul>

Before this page will work, we need to configure some blog settings. Remember how we added

activate :blog do |blog|
  #set options for blog
end

to our config.rb in the beginning? Delete the comment and replace it with:

blog.tag_template = "tag.html"

Restart your server and go to: http://localhost:4567/tags/space.html. You should see a page that lists both of your posts that you’ve tagged with space. If you change the url to http://localhost:4567/tags/aliens.html, it should only show you posts tagged with aliens.

Layouts

Bitters gave us some nicer typographic defaults, but other than that our pages are pretty bare bones and a little disorganized. Let’s make some moves toward a more blog-friendly layout for both the home and tag page as well as the posts themselves.

Base Layout

For our home page and tag pages, we’ll create a two-column layout - a side bar with links and a quick bio and a main section with previews of all our posts. We can achieve this by using the Neat grid system (or any grid system of your choosing).

Markup

In our layout.erb, let’s add a class called container to the <main> element. We’ll also add the following bit of code within <main before <%= yield %>:

<aside class="side-nav">
  <h1><%= link_to "My Blog", "/"%></h1>
  <p>Join me on a journey through space and time</p>

  <ul>
    <% blog.tags.each do |tag, articles| %>
    <li><%= link_to "#{tag} (#{articles.size})", tag_path(tag) %></li>
    <% end %>
  </ul>
</aside>

That <blogs.tags.each… block will give us a list of all the tags ours posts use and serve as a form of navigation.

Wrap <%= yield %> in a <section class=“post-container”> and we should have the building blocks to start adding some css to get our layout sorted out.

While we’re at it, let’s update our <title> tag to be something of our choosing.

Your layout.erb should look like this now:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>My ~ Cool ~ Space Blog</title>
    <%= stylesheet_link_tag "main" %>
  </head>
  <body>
    <main role="main" class="container">
      <aside class="side-nav">
        <h1><%= link_to "My Blog", "/"%></h1>
        <p>Join me on a journey through space and time</p>

        <ul>
          <% blog.tags.each do |tag, articles| %>
            <li><%= link_to "#{tag} (#{articles.size})", tag_path(tag) %></li>
          <% end %>
        </ul>

      </aside>
      <section class="post-container">
        <%= yield %>
      </section>
    </main>
    <%= partial "partials/analytics" %>
  </body>
</html>

Styles

Hop into your main.css.scss and add the following lines of CSS below the imports:

.container {
  @include grid-container;
  margin: $base-spacing auto;
  max-width: 960px;
}

.side-nav {
  @include grid-column(4);
}

.post-container {
  @include grid-column(8);
}

With just a few lines of SCSS, we’ve got a simple two-column layout set up! You can play around with your grid settings to get them exactly to your liking. Check out the Neat 2.0 docs for more on that.

Because this is our default template, you should see this layout applied to all pages in your site. Let’s tweak our layout just a little bit for our posts.

Post Layout

Create a new file called post-layout.erb in the source/layouts directory and copy/paster the content from out layout.erb files there. For the sake of simplicity, let’s say we don’t want to display the tag list in the aside here so we’ll delete the <ul containing the tag block.

There’s two ways we could apply this layout. The first is to go into each of our post files and add layout: post-layout to the front matter. The second method is to add the following line to your config.rb:

blog.layout = "layouts/post-layout"

You should see that your post pages contain the sidebar, but no tag list now! You can do a lot more with layouts to create entirely different layouts for your post pages. You could even give different posts different layouts if that’s your thing.

For more on layouts, check out the Middleman docs.

Article Summaries

Right now, the home and tag pages display the full text of our posts. This might not be a problem with just the one or two posts we have now, but it’s probably overkill as we keep adding to our blog. Let’s replace that body text with a summary instead.

In our index.html.erb (where we’ve defined how our list of blog posts should display), delete <%= article.body %> on line 5 and replace it with <%= article.summary(250) %>. You can replace 250 with however many characters you want to display for your summary.

If you refresh, you should get an error telling you to add ‘nokogiri’ to our Gemfile. We’ll add gem "nokogiri" to our file then run bundle install in your terminal. Restart your server and you should see that your home page and tag pages now display a summary rather than the full text.

Deploy

You have a few different deployment options with Middleman. You could configure your build to deploy to your hosting service of choice, use GitHub Pages or even use a good old fashioned FTP client like Cyberduck.

The thoughtbot template is ready to deploy with Netlify. Netlify makes it dead simple to deploy your site with their web interface or with their CLI and includes CDN, continuous deployment, 1-click HTTPS and more. I like using Netlify because it makes deploying from a GitHub repo simple and easy and they have a basic free plan for prototypes and small websites.

If you haven’t already, set up a new repository on GitHub. Once you’ve completed that, deploying to Netlify is incredibly easy. Since you copied or forked this from the thoughtbot repo, there should be a “Deploy to Netlify” in the README. Tap that button, follow the prompts, and your new site should be up and viewable on the web in a couple of minutes.

Conclusion

You can do a lot with blog templates and posts in Middleman and hopefully this tutorial has given you a good foundation to build upon. Happy coding and don’t forget to share what you build with us!