I’d like to demonstrate how template inheritance is or can be done in some template engines (Django, Jade, Handlebars and Freemarker in particular) because I think it’s one of the most important - if not the most - features of a modern templating language.

The first template engine I’ve ever used was Django’s in 2008 or so. It turns out that it was - and still is - one of the best template engines out there, which is proved by the fact that it has been implemented in many programming languages over the years. There is, for example, TWIG for PHP, Swig for Javascript, Liquid for Ruby and Jtwig for Java.

So how does template inheritance work? There is, at least, one base template that defines “placeholders” for, for example, the title, scripts or content. The templates inheriting from this base template, merely fill these placeholders without having to bother with everything else around it like the header, footer or navigation elements.

Django

Here, base.html represents the base template and index.html the inheriting template.

base.html:

<!DOCTYPE html>
<html>
<head>
  <title>{% block title %}Default{% endblock %}</title>
</head>

<body>
  {% block content %}{% endblock %}
</body>
</html>

The base.html defines two blocks, the title, which prints “Default” if none is provided by the inheriting template, and content which fills up the whole body tag.

index.html:

{% extends 'base.html' %}

{% block title %}Welcome{% endblock %}

{% block content %}
    <p>Welcome to Django</p>
{% endblock %}

The index.html extends base.html and implements the two blocks title and content.

A neat feature is that you can render the block content from base template by calling block.super.

So for example:

{% block title %}Before {{ block.super }} After{% endblock %}

would result in: “Before Default After” because the default block content is “Default”.

Jade

Jade also supports inheritance as a core feature. The base template here is called layout.jade.

layout.jade:

doctype html
html
  head
    title
      block title
        | Default
  body
    block content

index.jade:

extends layout

block title
  | Welcome

block content
  p Welcome to Jade

You also can also, instead of replacing the base block, append or prepend to it:

append title
  After

or:

prepend title
  Before

But you cannot include the base content where you want as you can in Django.

Handlebars

Handlebars unfortunately does not support inheritance out of the box. Some implementations or helper libraries include block helpers, that enable inheritance, but there is no certainty that it’s implemented.

For an experimental Java Framework called Linch, that uses Handlebars, I’ve implemented my own block helper which, in combination with partials, makes inheritance possible.

base.hbs:

<!DOCTYPE html>
<html>
<head>
  <title>{{#block "title"}}Default{{/block}}</title>
</head>
<body>
  {{{block "content"}}}
</body>
</html>

index.hbs:

{{#partial "title"}}Welcome{{/partial}}

{{#partial "content"}}
  <p>Welcome to Linch</p>
{{/partial}}

{{>base}}

The index.hbs defines two partials and then renders the base.hbs at the end, which results in the two block helpers looking for partials with the names title and content and including them in the template.

Freemarker

Freemarker also doesn’t officially support inheritance but you can simulate it by using macros. Your base template is basically one giant macro and the blocks are the macro’s parameters.

main.ftl:

<#macro main title="Default">
  <!DOCTYPE html>
  <html>
  <head>
    <title>${title}</title>
  </head>
  <body>
    <#nested/>
  </body>
  </html>
</#macro>

index.ftl:

<#import "main.ftl" as layout>

<@layout.main "Welcome">
  <p>Welcome to Freemarker</p>
</@layout.main>

Freemarker macro calls can have, besides parameters, a body, which can be accessed by the macro with <#nested/>. This is used as the templates main content. The templates don’t look pretty, but it works by just using macros.

Velocity also uses macros, but they do not have bodies. Therefore inheritance can only be implemented using an additional framework like Sitemesh.

Conclusion

Django probably still has the most powerful inheritance mechanism, particularly because the content super block can be called anywhere inside the inheriting block.

Jade works very similar and I think it has solved adding content to a block very elegantly with “append” and “prepend”, even though you have not the ability to use it both simultaneously. But most of the time you don’t need to anyway.

Handlebars is a widely used template language but it’s unfortunate that there isn’t a default block helper in the core or at least in all implementations. But the helper mechanism is very powerful and you can do it with not too much effort on your own.

The Freemarker way by using macros feels more like a workaround but it keeps it simple and shows that a lot can be dont with macros.