
Hiccup – A subset of Clojure used for generating HTML - mseri
http://hiccup.space
======
loevborg
For my money, _hiccup_ (and thus _reagent_ ) get the syntax for generating
HTML trees right. It's one of those things that I always thought didn't
matter, until I tried it.

Something that is very useful is that hiccup automatically ignores `nil` when
putting together contents, so you can use

(when pred [:div "..."])

if you want to show a div conditionally.

~~~
nilliams
Could you explain why the trade-off of 'just-html' vs the overhead of pre-
processing so you can use this not-quite-html-with-weird-parens syntax is
worth it?

To me it looks considerably worse than other nicer-than-HTML syntaxes like
Haml and Jade and I'm not sure what the supposed benefits are of writing it in
a lispy, paren-y style -- is there really a homoiconicity benefit here as that
seems especially unlikely when dealing with already-declarative code that is
designed to be dumb.

Aside: I always feel like the homoiconicity argument is completely the wrong
trade-off -- sacrificing readable syntax for the ability to write easier
macros? What team has ever been happy to find out that one of their team
members thought themselves smart enough to start writing macros?

Don't get. I bought the Clojure book and I less-than-half-get-it (as
demonstrated by my above stance on homoiconicity) and if someone held a gun to
my head and made me write a web-app in ClojureScript I'm pretty sure I'd still
use a conventional templating engine for my HTML templates (mustache-style +
HTML).

Would love to be persuaded otherwise because I'm thoroughly confused by this
everything-as-an-s-expression mentality of lispers and I'm concerned about the
amount of dust gathering on my Clojure book.

~~~
loevborg
Well, the advantages are more evident when you generate HTML dynamically from
any source. Typically the data you want to render will already be passed in in
the form of Clojure data structures (sequences). With hiccup syntax, all you
need to do is produce yet another clojure data structure. This gives you a
very simple task: when I have _this_ vector, how do I produce _that_ vector?

Because you're basically massaging vectors and maps, you have all the standard
tools from `clojure.core` at your disposal. As an example (untested):

    
    
      (def render-posts [posts]
         (->> posts
            (map (juxt :title :url))
            (filter (fn [[_ url]] (not (empty? url)))
            (map (fn [[title url]] [:ul.titles [:a {:href url} title]]))
            (into [:div.titles]))))
    

If you're not sure how to get there, you can play around in the REPL with test
data, adding one step after another until you have the right structure of
vectors. With time, working with these structures becomes second nature.

~~~
escherize
Just tonight I created a read only dashboard from a seq of business-logicy
data maps. Making tables and specialized formatting by applying functions is a
breeze with this approach.

------
jwr
It's funny how after using this syntax for a while with a structured editor
(Emacs+Paredit), HTML seems so crude, unreadable and difficult to edit in
comparison. I can't even imagine going back.

I write apps with React, Rum and Semantic-UI, and the resulting code is really
nice to read. You get things like:

[:div.three.wide.required.field [:label "Name"] [:input ...]]

(incidentally, I use Sablono, not Hiccup, but it doesn't matter, the syntax is
the same)

------
virmundi
I just started using hiccup for my project. I figured if I was going to go
Clojure, I should really go Clojure. It has been great.

The data structure is HTML structure makes it easy to manipulate things.
Coupled to a functional language where I can pass functions around in the view
(try doing that within JSP), I get a lot of reuse. I couldn't get the same
level of reuse if I was using a string templating system.

------
philjackson
Have a look at reagent too. Different paradigm (React-based) but very similar
syntax.

[http://reagent-project.github.io/](http://reagent-project.github.io/)

~~~
dkersten
The hiccup.space site itself is written in reagent.

~~~
escherize
That's correct! (Source: I'm the author)

~~~
dkersten
Yep, I checked the chrome react dev tools :-)

Great work, btw.

------
ChaoticGood
You might also enjoy Andreas ‘Kungi’ Klein explanation of Hiccup in his talk
titled "Frameworkless Web Development in Clojure."

Source is from the ClojureD conference in Berlin, Germany and Published on Feb
23, 2015

Highly recommend watching and it is only 32 minutes in duration.

[0]
[https://www.youtube.com/watch?v=_LghX4oDWcY](https://www.youtube.com/watch?v=_LghX4oDWcY)

------
danneu
Hiccup is a pleasure to use. Everything from template inheritance to view-
layer functions become trivial to do yourself since it's just some
datastructures. Using the same tools (paredit) to edit html that you use to
edit Clojure makes html finally tolerable.

However, its big drawback is that it's unsafe by default. You have to opt in
to escaping everything you send through it.

Though I believe Reagent's Hiccup-like syntax and
[https://github.com/r0man/sablono](https://github.com/r0man/sablono) (for Om)
are safe.

------
lhorie
If this looks interesting, but Clojurescript is prohibitive to you, Mithril (
[http://mithril.js.org/](http://mithril.js.org/) ) has a similar write-css-
selectors-a-la-Emmett-to-get-html templating syntax, but in plain js (
[http://mithril.js.org/mithril.html#usage](http://mithril.js.org/mithril.html#usage)
).

</shameless-plug>

------
divs1210
I absolutely love Hiccup and Reagent. Thanks a lot, authors and contributors!

------
davexunit
How many re-inventions of SXML must we see for Clojure?

~~~
a-saleh
Well, hiccup seems to be more than 5 years old, and I don't know many more
SXML reinventions in the ecosystem :-)

------
escherize
Author here. I really think this is missing the key features that could help
sell hiccup to non-clojure devs. The main benefit of using hiccup (I use
reagent on the frontend) is the ability to define functions that return hiccup
dynamically.

Having a function who's job is to take a map and turn it into hiccup is
extremely powerful, wether you're building a card-like interface, a table, or
really anything.

------
malandrew
matt esch's virtual-dom has very similar syntax as this for anyone looking for
the same with JavaScript:

[https://github.com/Matt-Esch/virtual-dom](https://github.com/Matt-
Esch/virtual-dom)

Makes server-side and client side rendering a cinch. Here is an example of it
in action in mercury:

[https://github.com/Raynos/mercury/blob/master/examples/serve...](https://github.com/Raynos/mercury/blob/master/examples/server-
rendering/server.js)

