davidhaslem.com

Ruby Site Options

When I decided to redesign my site, I decided I wanted to use Ruby for it, but wasn’t sure what to use. My initial thought was to go with Orange - but I decided I wanted something a bit nerdier. A site I could update from the command line with git.

Jekyll generates static HTML, giving me the flexibility to try out different HTML, Javascript and CSS tricks on the fly.

Keeping Awesome Tools

I recently started using SASS, and I already know I won’t be able to live without it. Unfortunately Jekyll likes to work with static files, so to use SASS, I have to run it as a separate process before running Jekyll. I’ve also decided I want to start using Sprockets to help make working with various JS plugins easier, adding another step to the process.

Unfortunately, all of these extra steps need to be run every time a file changes, which is kind of a pain. That’s where Rake comes to the rescue. I created a simple rake task to run all of the processes in sequence so now I just need to run rake generate to generate the latest version of my site (it runs, sprockets, then sass, then finally jekyll).

What if I forget to run rack generate before pushing my site live? To handle this likely future event, I built a pre-commit hook to run rake generate every commit and add any change to the commit. This seems a little hackish, but at worst it just means I waste an extra second regenerating my site. Git is smart enough to notice if nothing actually changes.

Meet Mr. Hyde

One thing I don’t like about the setup is that there’s no good way to preview it. Using the standard Jekyll preview functionality I can’t preview my site with SASS and Sprockets support. I have to run those separately. So this means I’d end up running rake generate every time I make a CSS or Javascript update… not fun.

Luckily, it’s really easy to create a Rackup script that will run them all for me, on the fly. I cobbled together a few Rack Middleware plugins and voila! A Jekyll preview server with SASS and Sprockets baked in.

  require 'rack'
  require 'rack/contrib/try_static'
  require 'jekyll'
  require 'sass/plugin/rack'
  require 'rack/sprockets'

  class MrHyde
    def initialize(app)
      @jekyll = Jekyll::Site.new(Jekyll.configuration({}))
      @app = app
    end
    def call(env)
      @jekyll.process
      @app.call(env)
    end
  end
  use Sass::Plugin::Rack
  Sass::Plugin.options[:css_location] = "./css" 
  Sass::Plugin.options[:template_location] = "./_sass"
  use Rack::Sprockets,
        :load_path => '_javascripts/libs',
        :hosted_at => '/js',
        :source => '_javascripts'

  use MrHyde
  use Rack::TryStatic, 
      :root => "_site",  # static files root dir
      :urls => %w[/],     # match all requests 
      :try => ['.html', 'index.html', '/index.html'] # try these postfixes sequentially
                                                     # otherwise 404 NotFound
  run lambda { [404, {'Content-Type' => 'text/html'}, ['whoops! Not Found']]}

So if I’m previewing my site, I can see changes to JS, CSS and HTML instantly with a simple refresh to my browser. I’m thinking about working in an automatic refresh too - Auto Refresh on File Change the Ruby Way, but I have to be careful not to get myself stuck in an infinite loop (refreshing the browser will trigger file changes… causing a browser refresh… etc.)

So that’s my site. If you want to give it a spin yourself, in true Jekyll fashion you can just fork my repository and start hacking away.