Why Enlive is not used more as an html template engine?

Enlive or anything similar.

Once it clicks, all the api abstraction makes sense. It’s just plain html, you inject parts into it using css selectors, enlive gives you good tools for making templates.

The workflow I imagine is the following: you decouple your work with designers, they just give you nice looking html with example content, from which you make snippets without touching the files, just by selecting things, and then compose templates using said snippets.

I know it’s slow, but is it prohibitively slow for webapps? Or there are other issues?

Update: I mean good old rails-style webapps, where html is generated server-side. I’m not talking about react, it’s a different thing, Enlive probably can’t help with building components.

Lots of reasons for me personally, even barring the fact that I have to work with React:

  • Not a fan of special macros
  • Not a fan of code and markup separation - impossible to have a full mental picture by looking just at the code. I dislike Selmer for the same reason, although I still use it for some niche cases
  • Selectors are not a robust solution, in complex projects there will be plenty of situations where you’ll have to come up with some unique selector yourself. It’s just an unnecessary trouble

Overall, it’s just increased cognitive load with decreased robustness.

you decouple your work with designers, they just give you nice looking html with example content, from which you make snippets without touching the files, just by selecting things, and then compose templates using said snippets.

It might work, but only if you use some utility classes CSS and almost never write your own CSS. Although it’s a more general problem of separating component design from website development - it surfaces regardless of the particular technology one might be using. More often than not, at least based on my personal observations, it ends up being one of the two: either the designers also know or learn how to write JSX (or maybe Hiccup), or they create UI mockups in Figma and similar tools and you, as a developer, implement that look in code.

I updated the post. React is a different thing, it’s about applications run in browser, Enlive probably can’t help in the workflow for building them.

To me, in case of rails-style server-side rendering, Enlive can actually help a lot, since it encourages making templates as pure functions and the views become completely logicless.

Yeah, I get the point about the cognitive load, but I disagree, because we live in repl, where it’s easy to test Enlive snippets, which in this server-side-rendering-world work as an analogue to components in react world.

Isn’t testing Hiccup in REPL even simpler? You can get Hiccup itself (which is IMO much easier to read than HTML), or you can get its HTML representation. And with it being a plain CLJ data structure and not some opaque snippet somewhere, you can use all Clojure tools with it (built-in functions in any manner, REBL, Portal, Reveal, serializing/reading/caching,…)

I’d say there are quite a few people using enlive. Judging by the number of downloads at least suggests so.

Well, with enlive you don’t directly interact with html, it gets converted to a nested data structure that can be worked with in a similar manner. But that’s not the point, we can convert this data structure or the resulting html to hiccup.

My question is: why is this separation of markup and code not widespread? Do I miss something?

To me the appeal is in this: we can render an html template with sample data in desktop and mobile browsers just by opening the corresponding html file, and see how responsive it is, how well it works. And then we can, well, enliven it by extracting snippets using css selectors and composing a view.

Why instead of this it’s so common to see representation and logic so intertwined together, to the point that they are completely inseparable?

Oh, two million downloads, cool. I wonder why the kit framework doesn’t go this way. Their approach is still to mix views with logic.

Can’t speak for other people, but I share the same sentiment as @p-himik. Hiccup is just so much more convenient. Personally couldn’t care less out about separating out logic, that just makes everything so much harder. I have used many different template engines over my 20+ years career, nothing is even remotely close to Clojure+Hiccup for generating HTML. IMHO, YMMV.


I mean, hiccup is equivalent to html. It almost literally is html. You still have to compose it.

I’m talking about the simplest thing ever: selecting and replacing a <div id="replace-me"></div> (or a [:div#replace-me]) with a snippet.

Well, if you find this approach not easy nor simple, that’s ok, but I’d still like to know why. In what way is this workflow complicated?

If you ask me markup is code. Therefore you are trying to split what can and should be one into two, with one thing even using an entirely different language.

Why replace anything? Why not just generate what you want in the first place? Without having a separate thing that you need to replace?

Yes, many designers probably don’t want to touch hiccup/clojure. But I can still take their HTML and just copy&paste the part I’m working on into Cursive. It’ll convert that to hiccup for me automatically.

I have also tried the “completely static HTML template” approach before, but it always failed as soon as you add even basic logic. Say you want to create a form that displays error messages and puts an “error” class and message somewhere. So, the HTML either shows no errors by default, or errors that you then need to “remove” in code. Often there are more than error true?/false? conditions, ie. a cond/case with 5 branches In the end the templates I get from designers never look anything like the final template needs to. At least never did for me.

Say you build some shop website listing 3 products next to each other. The HTML I get from my designers, if I even get any, has three dummy products. I take one div and

(defn html-products [products]
    (for [{:keys [title]} products]
      [:div.product [:div.product-title title] ...])])

or something like that. Very precise and everything where it should be.

With the HTML approach I now have to first find the correct selector, delete unwanted elements, delete/add unused classes, add conditional elements, splice text. All this while looking at two separate files with one being in super verbose gibberish syntax. :wink: If I have to edit the files I get some designers anyways, I know which route I’m taking. Also note that and changes to the “template” HTML, even if done by designers, will likely often mean you need to touch the code modifiying it again anyways. So, I’d rather do it directly, even that means I’m the one doing the edits. Using CSS classnames/ids to “target” specific elements, ie. jquery style, is also a terrible pattern that needs to die quick death, but again IMHO, YMMV.


Hm. Your code is fine, we all got used to this.

But there is a whole dsl for transformations, and they are not hard to read, here’s a for loop from the tutorial:

(transform herd [:tr.per_animal_row]  
                             (clone-for [i (range 4)] 
                                (set-attr :name (new-name i "true_name"))

                                (set-attr :name (new-name i "species"))

                                (set-attr :name (new-name i "extra_display_info"))))

Why do css-style selectors elicit negative emotions at all?

Conflict-galore, also naming things is hard. In code I’ll often end up with something that represents a “container”. Can’t have too many <div class="container"> without needing to get awfully spefific with nested selectors. Or you start using this like product__container description__container which gets old very quickly too.

I also prefer not to have name stuff, thats why I created shadow-css. This also eliminates the need to have a 3rd (.css) file open. I prefer just the one CLJ file. :wink:

Enlive is totally fine to use, if you like the approach by all means use it. You just asked why not more people use it and now you have 2 answers for possible reasons. I’m sure there are many other people with totally different reasons.

1 Like

Well, I’m talking about css-style selectors, not css itself. Yeah, ok, I see your point, but I politely disagree, I don’t find regular templates easier to work with.

Cool project though. I love tailwind, but occasionally something simpler to configure is needed, I’ll try it.

We used Enlive for a while at work but gave up on it for much the same reasons that @thheller and @p-himik provided.

We use Selmer for templates that need to be edited/read by designers and business folks who are used to HTML.

We use Hiccup for generating HTML fragments to embed in pages (which are generally Selmer templates).

1 Like

hi Alejandro,

my personal reason for not using Enlive is very straightforward: i do not like to work in HTML, period. i find HTML overly verbose, and so i have always sought some DSL (such as hiccup).

Well, that’s the usual approach. Ok, it seems I have to try and use it extensively to see the downsides myself.

1 Like

You don’t have to work with html directly, it’s about css-style selectors. You still have ids and classes with hiccup.

oh, i see. my mistake. perhaps it ought to take a second look.

If you constrast @thheller’s hiccup snippet with your enlive snippet, for one, I have no problem understanding what the former does. It’s all basic clojure, and I can trivially map it to html in my head. In the enlive-example, I have to learn a new dsl, which IMO has to bring a lot of value to justify the mental overhead.

Also, since hiccup is plain Clojure data structures, I have all of clojure.core available to me to manipulate it in any way I want.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.