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
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.
;; 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.
;; 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.
;; 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.