Enlive is a Clojure web templating library that combines vanilla HTML templates with backend logic. It’s a perfect separation of logic and frontend development in that it does not require frontend developers to know anything about the backend platform – only pure knowledge of HTML (maybe JS, CSS) is required.

I’m working with a Haskell web project based on Snap. Snap’s Heist template is logic-free, but somehow it still requires some domain specific knowledge of the Heist template. Moreover, the compiled version of Heist template requires some more tweaks, making collaboration a bit difficult.

I want to make a templating library that mimics Enlive in Haskell. It reads HTML document and transforms to Blaze-html, which is believed to be the fastest HTML generators available up till today. What I want to do is to allow developers to specify certain selectors and attach code snippets written in Blaze-html DSL, just like the following (pseudo-)Haskell code:

"#my-class" `embedContent` $ do
    forM posts $ \p ->
        li $ toHtml p

which does the following transformation:

<ul class="my-class"></ul>

to

\posts -> do
  ul $ do
    forM posts $ \p ->
        li $ toHtml p

What I have done so far, is creating the template library Piglet. Here is a quick look:

import           Text.Html.PigLet
import qualified Text.Blaze.Html5 as H


page = defTemplate [] "hello.html" [
  D "title"             >@< embedContent [| H.toHtml "Hello Piggies!" |]
, A ("class", ["page"]) >@< updateAttr [| addAttr ("id", "page-wrapper") |]
]

I like these >@< symbols. It’s like a cute pig looking at food!

The template is far from perfect. What I feel right now is that the syntax is not quite clean as it requires template Haskell quosiquotations. Also, the type signature is not quite nice – it’s a mere Q Exp. I plan to hide it under the hood. Also, currently, variables are referenced with string names, which might look a bit clutter (altough it does not affect any runtime efficiency).