Hiccup: Organizing Templates Using Multimethods
There are two major templating libraries for Clojure, Enlive and Hiccup. Since I am not that much of a designer, I chose Hiccup for my side project written in Clojure. I liked the DSL’s unification of code and templating; right in my comfort zone. This post is a little log on how I ended up using multimethods for organizing my Hiccup template functions.
DRY in Jinja
In my previous Flask projects, Jinja was my templating engine of choice. The DRY flow in Jinja templates consists of setting up a base.html
with a common layout markup. The ‘children’ would then ‘inherit’ and optionally override those blocks in their own templates.
Composition in Hiccup
However, In the world of Clojure (and therefore Hiccup), functions (duh!) are used to modularize templates. For example,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Multi-methods
In the above example, there is a chance of repetitiveness of functions like get-page
as the number of routes increases. In most cases, there is one (or few) container div
that changes across the templates. To avoid this, I have found using multimethods
to be a great way of dispatching templates at runtime.
For instance,
1 2 3 4 5 6 7 8 9 10 11 |
|
Now that I have a group of ‘container’ divs, I can invoke them from get-page
like so,
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Meanwhile, my routes
will end up looking something like this,
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
As you can see, get-page
is the point of entry for my templates and the container div
is injected according to the dispatched function. In fact, by abusing using compojure’s route destructuring, we can have true runtime dispatching of templates!
1 2 3 4 5 |
|
get-page
function isn’t going to change much and I can mix and match templates as much as I want.
I must admit that I am super new to Clojure. Therefore I am not sure if this approach is idiomatic enough in the Clojure world. Would love to hear suggestions on how it is usually done.