Middleman is a static site generator using all the shortcuts and tools in modern web development. – Middleman website
Middleman is my preferred tool when it comes to building static sites. Not only do I use it on all my deployed sites, but I use it even when I’m prototyping an application that will ultimately move into a different system. Let’s talk about static-site generators and, more specifically, Middleman.
Static-site Generators
You may have heard of static-site generators before. A static-site generator simply takes your pre-compiled (and pre-processed) languages like Haml, Jade, Sass, LESS, Stylus, CoffeeScript, and others, and compiles them into the equivalent language that is understood by the browser; HTML, CSS, and JavaScript, respectively.
As far as static-site generators are concerned, Middleman isn’t the only kid on the block. Similar tools, like Jekyll, and GUI-style applications like CodeKit, Hammer, and Mixture, provide a similar feature-set for compiling pre-compiled languages into static HTML, CSS, and JavaScript files.
Beyond compilation of those aforementioned languages, Middleman provides several features for rapidly building websites, such as:
- Creating master templates
- Creating partial files
- Template helpers (e.g.
link_to
,image_tag
, etc.) - Frontmatter (page-specific variables)
- Pretty URLs
- LiveReload (for rapid local development)
- Blog engine
- Creating/reading local data files (
.yml
,.json
) - Performance optimization (minifying, compressing)
- Custom, community-built extensions (deployment, s3, etc.)
Middleman > GUI Apps
Why do I think Middleman is a better tool than equivalent GUI applications? Wait, didn’t you just read my list above? Kidding; let’s dig into some more in-depth reasoning.
Rails - Models & Controllers
Middleman is written in Ruby, and it follows similar conventions to the Ruby on Rails framework. If you work in that environment, it will feel very familiar, minus the Models and Controllers. Being written in Ruby, Middleman provides more power than any of the GUI-style applications.
Gemfile
If you’ve ever worked on a Rails project, the Gemfile
will be familiar to
you. It holds all of the Ruby gems used on that particular project. Middleman
uses the same Gemfile
, so setting up a Middleman project is as simple as
running the following in the Terminal after downloading the project:
gem install bundler # If not installed
bundle install
That’s it. Middleman will go through and set up all the gems and get the
project ready. Start the server with middleman server
and you’re up and
running.
This only applies to existing Middleman applications. You’ll need to initialize and set up Middleman on new projects.
Layout
Middleman contains a layout file (inside the source
directory),
layouts/layout.haml
, that is your master layout for all of your pages. The = yield
block in the file is where the individual page content from each of your
view files will go. This is the same way that Rails layout files work.
You can create alternate layouts, or even nested layouts in Middleman.
Partials
In addition to the layout file, you can create as many “partial” files as you need. Let’s say that you have a header portion of your site that you reuse on several pages. You can create a partial file, and include that partial anywhere you need it.
%header.header
%h1 The Title
%p The subtitle for some secondary content.
I’ll be writing my HTML in Haml. If you don’t know Haml, I encourage you to take a look at the Haml site for more information.
In order to create a partial file out of our header markup, we simply create a
new file, _header.haml
, inside our source
directory. Now, let’s include
this partial file in a view file:
= partial 'header'
%p Here is some additional content on this page.
Notice the underscore (_
) in the filename. All partial files
start with an underscore. However, when we call the file, we don’t include
the underscore.
Template Helpers
Middleman comes with built-in helpers that you can use in your view files. Let’s take a look at a few of them.
Link Helper
= link_to 'Link Title', 'http://www.example.com'
Outputs:
<a href="http://www.example.com">Link Title</a>
Asset Helpers
= stylesheet_link_tag 'application'
= javascript_include_tag 'application'
Outputs:
<link href="application.css" media="screen" rel="stylesheet" />
<script src="application.js"></script>
Lorem Ipsum & Placehold.it Helpers
= lorem.sentence # returns a single sentence
= lorem.words 5 # returns 5 individual words
= lorem.paragraphs 10 # returns 10 paragraphs
Lorem ipsum text helpers
= lorem.image('300x400')
-# -> http://placehold.it/300x400
Placeholder image helper
Those are just a few of the many template helpers that Middleman provides. Be sure to read the documentation to learn about all of them.
Custom Helpers
In addition to the built-in helpers in Middleman, you have a file, config.rb
,
that allows you to write custom helpers that you can use in your view files.
Let’s look at a couple simple examples:
helpers do
def pretty_date(date)
date.strftime('%B %d, %Y')
end
end
config.rb
Here we have a pretty_date()
helper that we can then use in our view files to
format our dates:
%time= pretty_date('2013-12-03')
Haml <time>
tag
Which will compile to:
<time>December 03, 2013</time>
What if we wanted to add an active class to our navigation items, when on the associated page, to give a specific styling to that navigation element? Well, let’s create another helper:
helpers do
def is_page_active(page)
current_page.url == page ? {:class => 'is-active'} : {}
end
end
config.rb
And in our view file:
%nav.nav
%ul
%li{ is_page_active('/') }
= link_to 'Home', '/'
%li{ is_page_active('/articles/') }
= link_to 'Articles', '/articles/'
_nav.haml
partial file
And this compiled will look like as follows when on the Home page:
<nav class="nav">
<ul>
<li class="is-active"><a href="/">Home</a></li>
<li><a href="/articles/">Articles</a></li>
</ul>
</nav>
Compiled _nav.haml
file
Frontmatter
What in the world is “Frontmatter?” Is this a Star Trek thing? No, Frontmatter
simply lets you write a block of YAML
or JSON
data at the top of a view
file that you can then, in turn, use in that file. Let’s look at an example:
---
title: My Page Title
---
%h1= current_page.data.title
This outputs:
<h1>My Page Title</h1>
Now, this isn’t a very practical example, but you get the idea. We just add the Frontmatter declaration to the top of the file, and then we have the ability to use those variables within the page. Pretty cool, huh?
Frontmatter & Partials
Let’s look at a more advanced, practical usage of Frontmatter, but this time we’ll use it in conjunction with a partial file to show some of the power in Middleman.
First, we’ll create some Frontmatter. We want to add some variables about each of our blog posts that can be used in a post header partial.
---
title: Middleman
date: 2014-01-07
---
Alright. Now that we’ve defined a title
and a date
for this particular blog
post, we want to use that local data in a partial. How do we do this?
---
title: Middleman
date: 2014-01-07
---
= partial 'post_header', :locals => { :data => current_page.data }
Whoa! What’s going on here? Well, we’re including the partial just like we did
before, but we’re passing a second argument (:locals
), and passing the
current_page.data
, which is the Frontmatter for this particular page.
Now, in our post_header
view file, we have access to each page’s Frontmatter
through data
, and we can just output the correct markup.
%header.post-header
%h1= data.title
%time{ datetime: data.date }= pretty_date(data.date)
_post_header.haml
Notice how we’re using that same pretty_data()
helper that we
defined earlier to properly format our date.
And this compiles to:
<header class='post-header'>
<h1>Middleman</h1>
<time datetime="2014-01-01">January 7, 2014</time>
</header>
_post_header.haml
Local Data
In addition to using Frontmatter in individual files, you can also create a
YAML
or JSON
file at the root of your project, inside a data
directory,
that you can then use within your view files. Let’s look at an example.
We create a data/list.yml
directory/file to store a list of links that we
want to add to a page of our site. Instead of having to manually create new
markup, we can just write some simple YAML
, and then loop through and output
the data in the file.
links:
- http://drewbarontini.com
- http://envylabs.com
- http://www.codeschool.com
Now, in our view file:
%ul
- data.list.links.each do |link|
%li= link_to link, link
Which now outputs each of our links.
<ul>
<li><a href="http://drewbarontini.com">http://drewbarontini.com</a></li>
<li><a href="http://envylabs">http://envylabs.com</a></li>
<li><a href="http://www.codeschool.com">http://www.codeschool.com</a></li>
</ul>
Super simple and really useful.
Production-ready Configuration
In addition to just compiling assets and providing several helpers, Middleman allows you to specify a “build’ configuration for minifying your HTML/CSS/JavaScript, gzip-ing files alongside your regular files for your web server to serve up, and compressing images (via an extension). How do we do this?
In your config.rb
add the following:
activate :minify_html
configure :build do
activate :minify_css
activate :minify_javascript
end
In order to get the HTML minification to work, add this to your Gemfile
:
gem 'middleman-minify-html'
And then run bundle
to install that gem.
Now, when you run the middleman build
command, it will minify your HTML, CSS,
and JavaScript when building the static files.
Extensible
There is a fantastic community behind Middleman, and there are some great extensions that you can use in your projects. Take a look at the Middleman extensions directory to see what’s available.
Building the Static Files
Once you’ve written all your Ruby, Haml, Sass, and CoffeeScript using all these cool features in Middleman, you’ll need to build the static files. In order to do this, you just need to run the following command in the Terminal:
middleman build
Middleman will create a build
directory that contains the static files your
server will read. You can just upload these files to your web server via FTP,
and you’re good to go. Or, you can do some more fancy things with the
deployment. Let’s look at that next.
Deployment
Instead of manually uploading the build files to your server via FTP, we can
create a deployment script using something called a Rakefile
, which is just a
file that contains executable Ruby code. You have a few different options for
deploying your site.
GitHub Pages
A popular solution these days is to serve your site on GitHub
Pages. When you run the rake
task in the Terminal, which is
what is created in the Rakefile
, it will:
- Run the
middleman build
command - Go into the
build
directory - Initialize an empty Git repository
- Add the repository URL specified as the remote
- Add all of the build files
- Force push the files to the
gh-pages
branch
When set up correctly, you just run rake deploy
in the Terminal, and your
site’s static files will be automatically pushed up to your GitHub Pages site.
Awesome, right?
Be sure to follow GitHub’s documentation to familiarize yourself with the process for GitHub Pages.
FTP Server via rsync
If you have your own site with FTP, you can use something called rsync.
rsync is an open source utility that provides fast incremental file transfer.
The process is similar, but the files are transferred using rsync rather than Git.
You’ll need to be able to SSH into your server in order to use this method.
Getting Started
If you want to get started with Middleman, I’ve created a repository,
”Baseman,“ which is a base Middleman application setup that I like.
It uses Haml, Sass, and CoffeeScript, sets up the config.rb
the way I like
and, in the README
, there is instructions on creating those deploy scripts.
That’s All, Folks
That’s it. I hope you enjoyed this look at Middleman. There is a lot more to Middleman than what I talked about so, if you’re interested in learning more, I encourage you to take a look at the Middleman site.
Credit: I also want to give a shout-out to my friend, Arron Mabrey, who is the sole reason I got hooked on Middleman. I can’t thank him enough :)