This is a walkthrough of using enlive templates in clojure to populate an html page with a table of data.
This is the reference html as supplied by a web designer, the web designer is a very grumpy man and is insisting that you mustn’t change a line of his html or it will break when viewed with Lynx or IE 4.
Enlive is an html transformation library that uses CSS selectors to transform and alter existing HTML. In the same way that JQuery uses selectors to add animations or alter the DOM, enlive uses selectors and clojure code to transform and alter HTML without touching the HTML.
The fundamental operations in enlive are deftemplate and defsnippet. deftemplate defines a complete html template in which values can be substituted or altered. defsnippet is used to define fragments of HTML which can be used to construct complete HTML template. I’ll work through templating the HTML above to show how the complete page is built up from snippets.
This extract declares a variable that holds the location of the HTML file we are using as our template. The defsnippet declaration then defines a snippet based upon a the first th element in the first row of the table header that substitutes the value passed to the snippet into the content of the th element. The defsnippet form takes a name for the snippet, a base template, an expression that defines a CSS selector and a set of arguments, the body of the snippet contains a CSS selector matched with some code to execute. For this snippet we match the whole of the element with the [:th] expression and just substitute its content with the value passed to the snippet.
The REPL output shows the snippet being tested, internally enlive treats HTML as nested maps, if we change the base html, for example by adding a class and an id, this will be reflected in the snippet.
We can use this snippet to build up a larger snippet for the whole table header. Note how the whitespace in the template is being preserved in the output as the escaped tabs and newline characters.
Continuing this process of building snippets and combining them with standard clojure we end up with this:
This is a fair chunk of code but it does handle the special cases of odd and even rows and that the first table column uses a particular class without altering the HTML template. It could also be simplified by using some additional enlive functions and macros to remove similar code structures. Here is the output at the REPL for the whole table.
The code can then be used with other clojure libraries such as ring or compojure to produce a dynamic html table driven from data.