Reputation: 28807
How to elegantly render a conditonal list of menu items in Clojure's Hiccup-like data structures? My templating function ends up littered with calls to into
and does not read naturally.
Desired result:
[:div.menu
[:div.item "Home"]
[:div.item "Private"]
[:div.item "Private"]
[:div.item "Public"]
If I put the private items in an if
, I still need to unroll the returned vector, or deal with nil
, so this doesn't work:
[:div.menu
[:div.item "Home"]
(if authenticated?
[[:div.item "Private"]
[:div.item "Private"]])
[:div.item "Public"]]
I found I can use (into [:div.menu] ...)
and pass in a list of items, but it's unwieldy and doesn't read naturally. I ended up with this expression:
(-> [:div.menu
[:div.item "Home"]]
(into (if (auth/authenticated?)
[[:div.item "Private"]
[:div.item "Private"]]
(into [[:div.item "Public"]]))
Is there a better way?
Upvotes: 3
Views: 367
Reputation: 28807
Turns out Hiccup treats lists differently from vectors, so you can return a () instead of a [] and have it unroll correctly:
[:div.menu
[:div.item "Home"]
(if authenticated?
(list
[:div.item "Private"]
[:div.item "Private"]))
[:div.item "Public"]]
Upvotes: 3