Creating HTML with Hiccup

In the last recipe, we set up a server and returned some data. However, most people want to view HTML, not JSON. In this recipe, we'll take a look at Hiccup (https://github.com/weavejester/hiccup). This is a library that allows you to build web pages from Clojure expressions and data structures. It takes vectors, maps, keywords, and strings—or functions that return these—and turns them into HTML. This is a good solution for generating HTML from within Clojure web applications.

This recipe will build on the Serving data with Ring and Compojure recipe. I'll point out where you need to change or add things from that recipe, highlighting them as necessary. By the end of this recipe, we'll be serving a simple index page along with the census dataset.

Getting ready

First, we'll use the same dependencies in our project.clj file as we did in the last recipe, plus one more. Here's the full list:

  :dependencies [[org.clojure/clojure "1.6.0"]
                 [ring/ring-core "1.3.1"]
                 [ring/ring-jetty-adapter "1.3.1"]
                 [compojure "1.2.0"]
                 [hiccup "1.0.5"]]

We'll also add Hiccup to the namespace declaration, as shown here:

(ns web-viz.web
  (:require [compojure.route :as route]
            [compojure.handler :as handler])
  (:use compojure.core
        ring.adapter.jetty
        [ring.middleware.content-type :only (wrap-content-type)]
        [ring.middleware.file :only (wrap-file)]
        [ring.middleware.file-info :only (wrap-file-info)]
        [ring.middleware.stacktrace :only (wrap-stacktrace)]
        [ring.util.response :only (redirect)]
        [hiccup core element page]
        [hiccup.middleware :only (wrap-base-url)]))

How to do it…

In Hiccup, HTML is represented as vectors with keyword tag names and attribute maps.

  1. We'll define a function that builds a simple web page with a link to the data set:
    (defn index-page []
      (html5
        [:head
         [:title "Web Charts"]]
        [:body
         [:h1 {:id "web-charts"} "Web Charts"]
         [:ol
          [:li [:a {:href "/data/census-race.json"}
                "2010 Census Race Data"]]]]))
  2. Now, instead of redirecting the root URL, we'll have it serve the function, as shown here:
    (defroutes
      site-routes
      (GET "/" [] (index-page))
      (route/resources "/")
      (route/not-found "Page not found"))
  3. Now, when we run the server and visit the home page at http://localhost:3000/, we'll get something different, as shown in the following screenshot:
    How to do it…

How it works…

The Hiccup DSL is quite simple, and we can see examples of almost all of its syntax in this recipe, as shown here:

  1. We have an HTML tag with some text content, as shown here:
    [:title "Web Charts"]
  2. We have nested elements:
    [:head
      [:title "Web Charts"]]
  3. We can include attributes as a hashmap after the tag-name keyword:
    [:h1 {:id "web-charts"} "Web Charts"]
  4. Irrespective of the structure, we eventually pass it to one of the rendering functions. In this case, we're displaying it as HTML5, so we use this builder function:
    (html5

Hiccup also has a number of functions that can be used to insert links to CSS files and script elements. We'll see examples of these in the Creating scatter plots with NVD3 recipe.

There's more…

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.235.8