Last Updated: February 25, 2016
· rarous

Semantic templates with enlive and microdata

There are many ways how to deal with templates. But it is still a big deal to make your templates easy to change. Have you ever made some templates for Wordpress or other CMS? How you felt about it?

Imagine a world where you can use just plain HTML. No special directives nor magical helpers. Just HTML:

<article itemscope itemtype="">
        <h1 itemprop="name"></h1>
        <p class="info">
            <time pubdate itemprop="datePublished" datetime=""></time> |
            <strong itemprop="articleSection"></strong></p>
    <div itemprop="articleBody"></div>
    <footer itemprop="author" itemscope itemtype="">
        Author: <strong itemprop="name"></strong> |
        <a rel="bookmark" href="#" itemprop="url" title="Permalink">#</a>

This is a typical HTML5 template for a blog post. It uses new semantic features like sections article, header or footer, inline element time with pubdate attribute to denote publish date of article and microdata attributes for blog post.

Now we can take advantage of semantic markup. We will use small library to enlive our template without touching it.

(use 'net.cgrand.enlive-html)

(defn itemprop [name] (attr= :itemprop name))

(deftemplate blogpost-template "weblog/blogpost.html" [article]
  [:article :header (itemprop "name")] (content (get article :title))
  [:article (itemprop "articleBody")] (html-content (get article :html))
  [:article (itemprop "articleSection")] (content (get article :category))
  [:article (itemprop "author") (itemprop "name")] (content (get article :author))
  [:article (itemprop "url")] (set-attr :href (get article :url))
  [:article (itemprop "datePublished")] (content (long-date article))
  [:article (itemprop "datePublished")] (set-attr :datetime (utc-date article)))

Enlive uses CSS like selectors (written in clojure syntax) and transformation functions to manipulate template markup. Now your webmaster can change the visual elements, ids and classes, can add divs and spans, but our template will still work. Just because clever use of microdata.