Trick to get Jekyll to work with Liquid Inheritance

To homepage

One thing I missed while using the Liquid templating engine is template inheritance, which is something that Liquid doesn’t support out of the box. This is unfortunate, since I wanted to maintain a bunch of layouts for this website that inherit from a common base layout and override certain blocks of the template to customize things. Apparently, I was not the only one who missed it.

danwrong did too! The liquid-inheritance module implements Django-style inheritance in the Liquid templating language, which makes sense since Liquid templating looks very much like Django’s templating. It adds three tags to Liquid: extends, block, and endblock, which should work pretty much like Django uses them.

Sadly, liquid-inheritance does not work well with jekyll’s setup since jekyll sets up the locations of templates very differently from a normal Liquid system. Usually Liquid relies on a class like LocalFileSystem (see code here) to determine the location of the files you pass to the extends tag. jekyll does not make use of LocalFileSystem at all; its include tag, which overrides that of Liquid, uses simple paths relative to its _includes directory.

So I created a small jekyll plugin to add liquid-inheritance and make it jive well with jekyll’s directory structure:

require 'liquid_inheritance'

module LiquidInheritance

  class Extends < ::Liquid::Block
    def load_template(context)
      root_path = context.registers[:site].source
      file_path = File.join(root_path, context[@template_name])
      source = File.read(file_path.strip)
      Liquid::Template.parse(source)
    end
  end
end

I saved the code above in _plugins/liquid-inheritance.rb and all went well! Whenever I wanted to extend another template, I had to put its path related to the jekyll site root directory. So if I had a template base.html in the _layouts directory in jekyll, I would have to use the extend tag like so:

{% extends '_layouts/base.html' %}

Everything worked pretty well afterwards! However, the solution above is pretty much a hack since there is no guarantee future versions of liquid-inheritance will have the same load_template function in the same place. In the meantime, for v0.1.1 of liquid-inheritance the trick above works for me!