date: 2013/10/02

tags: foundation-sites, middleman

signup_zurb: "true"

featured_image: /blog/featured-images/middleman-foundation.jpg

Zurb Foundation is great. I mean really great. It is a Ruby Gem, it plays well with Rails and the Asset Pipeline. It even has its own generator to save you time. It also works well standalone with Compass and Sass from the command line but what happens when you try and use it with something else? Well, I will just come out and say it. Zurb Foundation doesn't always play well with others. In this Foundation Quicktip I will show how to get Zurb Foundation to play well with the excellent MiddleMan Ruby based static website and blog generator.

SPLIT_SUMMARY_BEFORE_THIS

MiddleMan is a fantastic static website generator that runs under Ruby. It is what I use to run this site and is one of the most flexible and least opinionated options on the market. OctoPress is much more popular, but just try and edit some of the basic themes. There is way more complexity in the templating system when compared to MiddleMan.

First lets add the zurb-foundation gem to our Gemfile:

gem "zurb-foundation", :require => false

:require => false is needed here so it doesn't load up all of the dependencies of the zurb-foundation gem.

MiddleMan can use Compass and Sass to compile your files but it will not work with out some extra configuration. Lets take a look at the modifications I made to the config.rb file.

set :css_dir, 'stylesheets'
set :js_dir, 'javascripts'
set :images_dir, 'images'

foundation_path = Gem::Specification.find_by_name('zurb-foundation').gem_dir
set :js_assets_paths, [File.join(foundation_path, 'js')]
set :sass_assets_paths, [File.join(foundation_path, 'scss')]

A blog post by Roman Ernst got me part way there. All that was needed was to add the :sass_assets_paths and everything works great.

Now lets take a look at my layout.erb file.

<!DOCTYPE html>
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!--[if lt IE 7 ]> <html class="ie6" lang="en"> <![endif]-->
<!--[if IE 7 ]>    <html class="ie7" lang="en"> <![endif]-->
<!--[if IE 8 ]>    <html class="ie8" lang="en"> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html lang="en"> <!--<![endif]-->
  <head>
    <meta charset="utf-8" />

    <!-- Uncomment to make IE8 render like IE7 -->
    <!-- <meta http-equiv="X-UA-Compatible" content="IE=7" /> -->

    <!-- Set the viewport width to device width for mobile -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title><%= current_page.data.title || "James Stone" %></title>

    <%= stylesheet_link_tag "app" %>
    <%= javascript_include_tag "vendor/custom.modernizr" %>
  </head>

  <body>

    <%= partial "header" %>
    <%= yield %>
    <%= partial "footer" %>
    <%= javascript_include_tag  "application" %>

  </body>
</html>

This should look pretty familiar if you use the Assets Pipeline / Sprokets in Rails. The only difference here is that we want to load vendor/custom.modernizr.js at the top of the page separately so I made a copy from the original gem file to my javascripts/vendor directory. You can find the path of to your current zurb-foundation gem(s) by running gem which zurb-foundation. The javascripts can be found one level down in the ../js/vendor directory.

Now lets move on to our app.js file.

This is a manifest file that'll be compiled into application.js, which will include all the files listed below.

Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.

It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the the compiled file.

WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD GO AFTER THE REQUIRES BELOW.

Here is the message in the comments of this file generated by MiddleMan that I have removed, for your reference.

//= require vendor/jquery
//= require foundation/foundation
//= require foundation/foundation.clearing
//= require foundation/foundation.abide
//= require foundation/foundation.forms
//= require foundation/foundation.section
//= require vendor/highlight
//= require vendor/processing
//= require_directory .

$(document).foundation();

// other code I want to load every page, such as my code highlighting library
hljs.initHighlightingOnLoad();

There are a couple things going on here. First, I am deciding to use jQuery only1 for my site because I have some jQuery specific functionality that is not compatible with Zepto. Second, you will notice that I am only including a subset of the full Foundation JavaScripts. This is because I am optimizing it by not including features that I am not using on my site. Finally I load two additional libraries I am using, highlight and processing from the vendor directory. Finally I have changed //=require-all to //=require_directory . This is important to prevent Sprokets from requesting all of our Foundation JavaScript files from the gem file. Now it will only look at the current directory for files to compile at the end of this file.

Against the suggestion of the MiddleMen I just place my JavaScript in the file, starting with the $(document).foundation() jQuery Plugin call.

Now, we are almost set to go but there is one more thing. Sassy CSS or SCSS. To get this working I have copied over the ../scss/normalize.scss and ../scss/foundation/variables.scss files from the gem file and renamed them with a prefixed underscore.

Here is the contents of my app.scss file:

// Global Foundation Settings
@import "settings";

// Comment out this import if you don't want to use normalize
@import "normalize";

// Import specific parts of Foundation by commenting the import "foundation"
// and uncommenting what you want below. You must uncomment the following if customizing

@import "foundation/components/global"; // *always required
@import "foundation/components/grid";

// Use this grid if you want to start using the new Foundation 5 grid early.
// It will change breakpoints to min-width: 640px and 1024px.
// @import "foundation/components/grid-5";

@import "foundation/components/visibility";
// @import "foundation/components/block-grid";
@import "foundation/components/type";
@import "foundation/components/buttons";
@import "foundation/components/forms"; // *requires components/buttons
@import "foundation/components/custom-forms"; // *requires components/buttons, components/forms
@import "foundation/components/button-groups"; // *requires components/buttons
// @import "foundation/components/dropdown-buttons"; // *requires components/buttons
// @import "foundation/components/split-buttons"; // *requires components/buttons
@import "foundation/components/flex-video";
@import "foundation/components/section";
// @import "foundation/components/top-bar";  // *requires components/grid
// @import "foundation/components/orbit";
// @import "foundation/components/reveal";
// @import "foundation/components/joyride";
@import "foundation/components/clearing";
// @import "foundation/components/alert-boxes";
// @import "foundation/components/breadcrumbs";
// @import "foundation/components/keystrokes";
// @import "foundation/components/labels";
@import "foundation/components/inline-lists";
@import "foundation/components/pagination";
@import "foundation/components/panels";
// @import "foundation/components/pricing-tables";
// @import "foundation/components/progress-bars";
@import "foundation/components/side-nav";
// @import "foundation/components/sub-nav";
// @import "foundation/components/switch";
// @import "foundation/components/magellan";
// @import "foundation/components/tables";
@import "foundation/components/thumbs";
// @import "foundation/components/tooltips";
// @import "foundation/components/dropdown";
@import "highlight-styles/solarized_dark";

Here I have left all of my commented out @import statements because when Sprokets renders the CSS it removes all // style comments and only preserves /* */ style comments. After all of my Foundation @imports I place all of my site specific Sass and CSS.

This has been working really well for me so far. First it is using the latest version of Foundation from the gem file and only requires minimal config changes to my MiddleMan config.rb file. I can just run middleman server and it will recompile scss changes on the fly so they are reflected immediately on my development server. Another great benefit it is the Sprokets assets system that provides a best practice creating a single concatenated and minified javascript and css file per site.

I host everything on AWS S3 / CloudFront and use the middleman-s3_sync gem to keep everything up to date.

If you have been using MiddleMan with Foundation or have any questions please feel free to get in touch through the comments below. Is there something strange you are trying to get Foundation Sass to work with? Let me know in the comments and I might featured it in a future post.

[1] jQuery only: If you want to have the default behavior of Foundation choosing Zepto or jQuery automatically, you can approach it as I did with the custom.modernizr.js file.