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!