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!