Way back in 2010, a blog post outlined a means to re-use your Rails application layout in your Jekyll static web site. This is an interesting exercise at least, and still relevant today, in 2015.
The last time I went out to look at the blog post, it took an extremely long time to load, so I’m reproducing the page here as well.
Brighter Planet’s blog
Posted by Andy on Monday, August 09, 2010.
In my last post I discussed how we share a single layout between Rails apps. This has been a lifesaver for us as we manage a half-dozen production apps. But a couple of our sites—our developer hub and this here blog—don’t use Rails. They’re both Jekyll sites running on GitHub Pages.
Obviously we can’t rely on the Rails Engine features in our shared layout gem to load the layout into the right places. What are we to do?
One step at a time
Luckily Jekyll already includes the basic building blocks of our solution: layouts and includes. Layouts, described here are Liquid templates, and Jekyll ships with a custom Liquid extension that enables includes.
All we need to do then is transform our Rails layout into a Jekyll layout and use includes instead of partials. Ready, set, go.
When in Rome
Jekyll is a static site generator. Following this lead, our transformations will be manually executed and staticly stored within your Jekyll site. The easiest way to get started is to set up a task in your Rakefile:
What’s going on here? Rake is fetching the raw ERB of your layout from
the gem’s repository, sending it to ERB for processing, and then storing
the result as your Jekyll site’s
I should call your attention to a couple of tricky bits here.
First, this business about bindings. ERB needs a “binding” to work–that
is, a context within which it can access instance methods, variables,
etc. Rails takes care of this for you, but since we’re invoking ERB here
directly, we have to tell it where to bind. Why is this important? Your
layout probably uses methods like
get its job done. If we don’t provide those methods in ERB’s context,
NoMethodError all over the place. The easiest way to fool
ERB is with a fake context, which we’ll put in
You can see how we re-interpret these method calls in a way that’s
meaningful to Jekyll. (Note that since
binding is a private method we
have to publicize it with the
The second tricky bit is dealing with your standard Rails layout’s
yield calls, the consequence of using
content_for blocks in
your views. We have to anticipate this and set up ERB to act
accordingly. Where do we even capture arguments to yield? Turns out the
correct place to do this on
get_binding, our wrapper to the private
binding method. Now the
yield we’re interested in—the one where we
want Jekyll content to go—is the one called without any arguments. So we
set the block to output the
content Liquid tag when it sees
called with an empty argument set. Other
yield calls—to dump
content_for material, which could never be prepared by Jekyll
anyways—are simply ignored.
And we’re done
Your complete layout package will probably include several partials—each
with its own fake context class in
stubs.rb—as well as asset files. To
build your layout from its source in the cloud, just