At a summer barbecue, a friend asked if I could build a website for his new restaurant. But what he didn't know was that I haven't built a static site in nearly a decade. However I couldn't let him spend thousands of dollars on a cookie cutter website designed by a firm that knew nothing about his restaurant.

We started coming up with ideas right away over a couple of beers. He wanted manageable content, an Instagram feed, and an easy to change restaurant menu. It quickly started sounding like a full on Content Management System and not a simple website. I had to reel in this ambitious project before it became a feature sink. So we decided to just make a beautiful static site.

I started using Wordpress to build the website because I've used it in the past and it's easy to expand. With a list of dream features in mind, a basic website quicky emerged. But as it grew, themes became complicated to build. Plugins were ugly and difficult to customize. And templates were clunky to use. I couldn't continue with the Wordpress route.

Having been spoiled by component based systems, I decided to try Next.js. I use React in my day job, so it's familiar ground, but I couldn't justify the complexity for a website that didn't need dynamic content. Also, Next.js had no CMS support.

That's when I decided to reach for hiccup, a Clojure library for generating server side content. hiccup let me use Clojure data structures to build my pages.

1
2
;; generating a span element with the class `foo` and content of `bar`
(html [:span.foo  "bar"])

This short syntax let me express more with less code. I also had components.

1
2
3
4
5
6
7
;; defining an `h1` variable with the content `Welcome`
(def header [:h1 "Welcome"])

;; using `header` variable inside a `div` with an additional paragraph
(html [:div.content
       header
       [:p "more content"]])

I could define functions or plain variables, then use them as components in my templates.

On top of that, I didn't have to learn a special syntax for working with data. I had the full power of Clojure to interact with data and components themselves.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
;; defining data for the menu
(def menu-items
  ["Crab Rangoon"
   "Pot Stickers"
   "Miso Soup"])

;; creating a function to generate a list elment from the provided `menu-item`
(defn create-menu-item [menu-item]
  [:li.menu-item menu-item])

;; generating an unordered list by mapping over the `menu-items` data
(def menu
  [:ul
   (map create-menu-item menu-items)])

I could do all this with a concise syntax that is simpler than Wordpress templates, and shorter than React components.

The final benefit is the ease of mind provided by Clojure. I know that no matter what features we dream up, they will be possible with this general purpose language.