Middleman is a static page generator that brings many of the goodies that Rails developers are used to.
Out of the box, Middleman brings Haml, Sass, helpers etc. However, it can be configured to do even better. This card is a list of improvement hints for a Rails developer.
Gemfile
Remove tzinfo-data
and wdm
unless you're on Windows. Add these gems:
gem 'middleman-livereload'
gem 'middleman-sprockets' # Asset pipeline!
gem 'bootstrap-sass' # If you want to use Bootstrap
gem 'byebug'
gem 'capistrano'
gem 'capistrano-middleman', require: false
config.rb
activate :livereload
activate :sprockets
configure :build do
activate :minify_css
activate :minify_javascript
activate :asset_hash
end
# Middleman fails to reload helpers, although it notices their modification
# This force-reloads them
Dir['helpers/*'].each(&method(:load))
# Disable warnings
Haml::TempleEngine.disable_option_validator!
You might want to activate :directory_indexes
. This tells Middleman to create Rails'ier URLs (/demo instead of /demo.html) with a little trick: It actually creates an index.html
in a subdirectory (/demo/index.html). Your webserver (e.g. Apache) needs to support this.
Localization
For localization to work, you need to:
# config.rb
activate :i18n, mount_at_root: false, langs: %w[en de]
Any page inside source/localizable
will be generated once for each locale in langs
. mount_at_root
is true
by default, which would put files of the first locale (here: en
) at the site root (e.g. /
), and only prefix the non-default locales (e.g. /de/
). Setting it to false
prefixes all locales.
Note there is no localized path helper. You need to prefix link href
s yourself (e.g. with a helper).
Helpers
Inside config.rb
, you can define helpers in a helpers { ... }
block. However, this does not scale very well. You're best off creating a /helpers
directory and putting helper files there just like you know it from Rails. Reminder: Middleman brings the handy helper methods capture_html
, content_tag
and tag
.
Environments
Middleman 4+ supports different environments. Think of them as config.rb
s you put into environments
, e.g. environments/staging.rb
. They will only be evaluated when running middleman for the specific environment. Default for the local dev server is development
, default for building is production
. Activate an environment with -e staging
or --environment=staging
.
Test for environments like this:
environment? :staging
Testing
Complex "static" pages might need some integration testing, especially if they contain complex Javascript code. To employ Cucumber with Spreewald Show archive.org snapshot and Selenium, add these gems to the Gemfile:
group :test do
gem 'cucumber'
gem 'spreewald'
gem 'capybara'
gem 'selenium-webdriver' # Only for running tests in a real browser (suggested)
gem 'capybara-screenshot' # Optionally
gem 'rspec' # Dependency of Spreewald
end
Now run bundle exec cucumber --init
and add this code to env.rb
:
Bundler.require :default, :test # Require default + test gems from the Gemfile
require 'capybara/cucumber'
require 'spreewald/web_steps'
middleman_app = ::Middleman::Application.new do
config[:environment] = :test
# Note that :build mode is the right way to test, because in production
# your site will be "built", too. However, testing in :build mode oddly
# takes thrice as long as :server: mode, so you might try and skip this
# setting for faster test runs.
config[:mode] = :build
end
Capybara.app = ::Middleman::Rack.new(middleman_app).to_app
# Only when using Selenium (suggested): Run all tests in Chrome
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome)
end
Capybara.default_driver = :selenium
You need the Google Chromedriver Show archive.org snapshot binary to use Chrome with Selenium.
Configure Capybara-Screenshot with this file:
# features/support/capybara_screenshot.rb
require 'capybara-screenshot/cucumber'
# Have HTML screenshot render with assets (while `middleman` is running)
Capybara.asset_host = 'http://localhost:4567'
module Capybara::Screenshot
# Monkey-patch: Screenshot location
def self.capybara_root
File.join Dir.pwd, 'tmp', 'capybara_screenshot'
end
end
Deployment
Run cap install STAGES=production,staging
.
When you're deploying with Capistrano, you might need to set :build_dir, 'build/public'
in config.rb. This will render the page into a public
subdirectory, which your Rails'ish webserver is already configured to deliver from.
Note that you must not require capistrano-middleman manually, although stated in the gem's README. Doing so would screw the underlying Rake tasks.
If you want to use different environments for different deployment stages, add this to the stage files:
set :middleman_options, %w[--environment=<your chosen env>]