Switching from Jekyll to Middleman
Remark (2020-03-19). My homepage underwent various framework changes. In retrospective and in most cases, the migrations have been motivated more by an intellectual challenge, rather than a technical limit of the technology being replaced.
As the date of writing I am using Org Mode for my homepage and Jekyll for other websites I manage. In the past I used Middleman, Sandvox, iWeb, and pure HTML when that was the only choice to write a webpage.
Table of Contents
I just switched my homepage from Jekyll to Middleman. The frameworks are very similar and the migration has been relatively painless. The following notes recap the motivations for the switch and what I had to to move to the new framework.
Remark. The following notes were written when I was using older versions of both frameworks, namely, Middleman 3 and Jekyll 2. Some of the remarks are still valid, others issues are now less relevant. I updated the post to reflect some of these changes, but some caution still has to be applied.
The main strengths of Middleman are, in my opinion:
- Support for
erbtemplates. Middleman allows one to use embedded ruby rather than Liquid for “dynamic” content. On top of a more familiar syntax, which makes the construction of dynamic content simpler and more flexible (to me, at least), this feature allows to reuse a template I developed for a Rails application.
- Generation of individual pages from data using the
proxydirective. Although I have not yet used this feature, the same trick in (older versions of) Jekyll requires the use of plugins. One of such plugins is Jekyll datapage generator
- Support for the asset pipeline and cache buster This has been further improved in Middleman 4.
- Simpler deployment. A Middleman extension supports deployment via
ftp. To achieve the same trick with Jekyll I had to define a Rakefile, which is available here: Jekyll Rakefile.
- The build command does not regenerate files which have not been changed. This comes at the cost of a slower compilation, but it can make deployment a lot more efficient, if you care to look at the creation dates of files.
- Simpler support for helpers. Middleman support helpers written in Ruby. This makes their development easier for me. The same trick in Jekyll requires to register a new Liquid filter and ends up in more code and more difficulties in managing multiple arguments.
- Support for multiple blogs. This is a feature Jekyll also has. The main difference is that Middleman’s blog extension has commands to generate articles and allows one to keep posts’ assets together with the posts.
- Access to sitemap and resources. The access to the sitemap and to resources (e.g., page content, page metadata) is well documented.
Some of the issues I have found with Middleman are:
- An incompatibility between the Sass release of Foundation 5.4.7 and the compass library required by Middleman. This is, in fact, more a problem with Foundation than with Middleman. The effect on websites based on Foundation is that changes to the default configuration are ignored. I have not yet found a good workaround and I’ll just wait for Foundation to release a version which supports more recent releases of Compass (most likely: Foundation version 5.5).
- Some compatibility issues between the versions of the gems used by
Rails and Middleman for asset bundling. I am not a good user of
bundle execand I ended up using
chrubytwo manage two independent sets of Ruby installations (
gem_homewould have been another valid alternative). 1
- Performances: Jekyll is (or at least seems to be) way faster. 1
Phase 1. Website up and running with no layouts
- Create an empty project with
- Move the Jekyll sources to the
- Rename each file to specify the chain of transformations you want
Middleman to perform. For instance:
index.textileshould be renamed
index.html.textile. If you want also want to use ERB in the file, add the
erbsuffix; e.g., rename the file to
- Change all Liquid markup to the corresponding
- Replace =include=s with =partial=s
- Optionally, use
link_toand the other helpers (e.g.,
image_tag, to simplify the way in which assets are referenced)
The steps above should be enough for a basic website. If you are using custom layouts, move to the next phase!
Phase 2. Migrate layouts and take advantage of Middleman features
- Move the
sources/layoutsand change the extension of all the layouts to
erb. Thus, for instance,
- Migrate all the Liquid markup to
<%= yield %>in place of
- If you are using nested layouts, you need to use the
wrap_layoutsyntax (Have a look at: https://middlemanapp.com/basics/templates/)
Phase 3. Activate specific features
- Modify the
Gemfileto include the extensions you prefer (e.g.,
config.rbto minify and compress assets, to bust cache, etc.
Deployment on a sub-Uri
This section has been superseded:
One critical point (both with Jekyll and Middleman) used to be, the
management of URLs, especially if the website is deployed on a sub-URI
http://www.example.com/a/b/c/). The problem is the way in
which URLs are interpreted. More in details:
- Using relative URLs (
x/y/z) in templates and pages is no good, because pages might be deployed at different levels of depth on the website, making relative references wrong
- Using absolute URLs (
/x/y/z) won’t work, unless you specify the full path (e.g.,
//domain/x/y/x/). This however, breaks the possibility of previewing on the local web server and makes re-deployment on a different URL more difficult.
- Similar to the previous point, using fully qualified names
http://domain/x/y/z) breaks the possibility of previewing on the local web server and of moving your website to a different location, if needed.
To solve this problem, when I started using Jekyll, I defined a
Rakefile to simplify the management of common Jekyll operations,
including deployment. The
Rakefile sets a variable
_config.yml. The variable can thus be pre-pended to all URLs used on
a website, to make them absolute.
Middleman supports a simpler solution. More in details, the
:http_prefix variable can be used to pre-pend a portion of a path to
URLs defined with the standard helpers:
Thus, for instance, if the website lives on
“http://www.example.com/a/b/c/”, it is sufficient to set
configure :build do set :http_prefix, "/a/b/c/" end
and Middleman will take care of replacing, e.g.,
<% link_to “p.html”
<a href“a/b/c/p.html“>=. (Notice that setting
:http_prefix to a full URL, like, e.g., =http:/…=, will cause an
The problem remains, however, with links defined using the native markup tags. For instance, Middleman will not replace the URL of links written in Textile (or Markdown).
The problem can be solved by defining a helper to generate absolute
URLs. Add to your
config.rb the following code:
helpers do def aurl url File.join(http_prefix, url) end end configure :development do set :http_prefix, "/" end configure :build do set :http_prefix, "/a/b/c/" end
and use the
aurl helper every time you want to insert a link or a path
using the markup of the templating language. For instance:
"Some link on my website":<%= aurl("some_page.html") %>
More in details, the following rules apply:
- If you are using one of the tags of the markup languages, always use
- If you are using
image_tagyou are fine
- If you are using
link_toyou are fine
Remark added on 2020-03-19