What does HackerNews think of enlive?

a selector-based (à la CSS) templating and transformation system for Clojure

Language: Clojure

I’ve done projects with enlive and quite enjoyed it. Allows a workflow where designers create pure HTML/CSS templates and you just fill in the blanks using selectors and transformations written in Clojure.

https://github.com/cgrand/enlive

It's not true though that you need logic in your templates - see https://github.com/cgrand/enlive for a counterexample.
Can you clarify what you mean by "simple templates"?

It may not be along the lines of what you're hoping for (it may not be simple enough), but I've found Stasis[1] to be a powerful tool for static site generation.

You can write plain old HTML pages and/or fragments, with your desired level or genericity, and then run them through a set of transformations[2] to fill in content, set attributes (e.g. classes, styles, whatever), un/wrap elements, and so on.

[1] https://github.com/magnars/stasis

[2] https://github.com/cgrand/enlive

ClojureScript with Enfocus (https://github.com/ckirkendall/enfocus/) in the front-end, and Clojure with Enlive (https://github.com/cgrand/enlive) in the backend. It's not a SPA. I started it a while ago, before React/Om. If it were now I would write it as a SPA and use some React wrapper, probably Rum (https://github.com/tonsky/rum).

As for HTML/CSS, no framework at all. I'm interested in simple, minimalistic, innovative design, and I don't think frameworks help to achieve that.

Flow control does not belong in markup.

My favourite templating system is enlive[1] (or enliven[2]). You use CSS-style selectors to select snippets of HTML to manipulate and then use code to duplicate, remove, move or replace these snippets, insert content, set attributes etc.

The "template" is pure HTML without any additional markup and without any logic. The code then says "repeat this snippet for every item in this list and insert it over there" (or whatever you need). Markup does what its good at, code does what its good at. Works out really nicely.

Although nowadays I use reagent and hiccup-style markup and write everything in code (but keep my components as pure and dumb as possible).

[1] https://github.com/cgrand/enlive

[2] https://github.com/cgrand/enliven

SSAX, SXML and SXSLT are available as a package for Racket:

http://pkg-build.racket-lang.org/doc/sxml/

`raco pkg install sxml`[1]

I was recently looking for an enlive[2]-like library to use with a Racket-based project and couldn't find one. Yes, Racket has powerful syntax manipulation and pattern matching[3] built-in, but I wanted functional transforms of X/HTML akin to what enlive gives me in my Clojure-based projects. SXSLT seems to fit the bill quite nicely.

[1] http://docs.racket-lang.org/raco/

[2] https://github.com/cgrand/enlive

[3] http://docs.racket-lang.org/guide/match.html

You might find Enlive (a Clojure library) interesting:

https://github.com/cgrand/enlive

See Brian Marick's 5-part tutorial for a good overview:

https://github.com/cgrand/enlive/wiki/Table-and-Layout-Tutor...

This is why I love Enlive[1], Enfocus[2] and Kioo[3] (and Enliven[4] is looking awesome too!).

Your logic stays in your code, the templates are snippets of pure HTML. Dynamic content is generated by manipulating and composing the snippets in code. Snippets can be defined in one large HTML file or many files - up to you. The code uses CSS selectors to choose which parts of the HTML to use and transform.

For example, lets say I have a blog application:

    \n        
Welcome to my Blog
\n
\n
\n
My post
\n
Post content here
\n
\n
A comment
\n
\n
\n
\n \n
\nThen my code might look something like this:

    (enlive/defsnippet comment-snippet "myfile.html"\n      [:.comments]\n      [comments]\n      [:.comment] (enlive/clone-for [comment comments\n                    (enlivecontent comment))\n\n    (enlive/defsnippet post-snippet "myfile.html"\n      [:#posts]\n      [posts]\n      [:.post] (enlive/clone-for [{:keys [title content comments} posts]\n                 [:.title]    (enlive/content title)\n                 [:.content]  (enlive/content content)\n                 [:.comments] (comment-snippet comments)))\n
\nThat is, parts of snippets are selected and transformed in some way (changing the content, adding/removing css classes or styles, setting attributes, prepending or appending content, wrapping or unwrapping tags, duplicating for each element in a list, etc). This lets you write your page elements as mocked up snippets with dummy data and then merge them together, fill in content, dynamically update attributes and classes all without putting any logic into the HTML.

This also makes it very designer friendly because they can work in pure HTML and CSS without worrying about templating - they only need to make sure to follow your basic structure outline (ie making sure your selectors match the right thing).

[1] https://github.com/cgrand/enlive

[2] https://github.com/ckirkendall/enfocus

[3] https://github.com/ckirkendall/kioo

[4] https://github.com/cgrand/enliven

At least for ClojureScript there is https://github.com/ckirkendall/kioo which is based on https://github.com/cgrand/enlive

I not sure there is a similar thing for plain React/JS though.

String templating is not type safe, operational transforms on trees (AST) can be type/structural safe.

Clojure https://github.com/cgrand/enlive

Python https://github.com/supervisor/meld3

> but in the real world you'll want your HTML templates separate and in a designer or front-end-coder friendly format.

For Clojure - it sounds like you're looking for Christophe Grand's work on enlive: https://github.com/cgrand/enlive

You can read a tutorial here: https://github.com/swannodette/enlive-tutorial/

Clojure is very capable for web development, but getting started is not as clear cut as it is with something like Rails or Django. This is because the Clojure community tends to eschew large frameworks, and instead prefers using smaller, more focused libraries. This provides a lot of flexibility, but is intimidating at first because it requires you to choose your own libraries for routing, db interaction, templating, etc.

Everything is to be built on top of Ring, which is the Clojure equivalent of Rack or WSGI. Compojure is pretty much the standard for routing at the moment. Korma is a very popular DSL for writing SQL. For templating, Hiccup and Enlive are popular, but there are other options as well.

I would start off by getting a decent understanding of Ring and Compojure and building from there.

--

https://github.com/ring-clojure/ring

https://github.com/weavejester/compojure

https://github.com/weavejester/hiccup

https://github.com/cgrand/enlive

http://sqlkorma.com/

http://www.clojure-toolbox.com/ is really helpful for finding appropriate libraries.

Depends on a) how comfortable you are working with HTML to begin with, b) what functionality you're implementing with your DSL, and c) how many people are working on the project? If you're someone with a lot of Python experience and no HTML experience, and you're doing a solo project, this is a perfectly appropriate.

One other area where abstraction is appropriate is form generation. I've used Django a lot and recently Clojure+Noir a bit, and in both of those I've ended up using an abstraction for all the form code (Django forms in the former, Hiccup+helpers in the latter). In the Clojure project I was even working with someone knew HTML and not Clojure, so most of the site is rendered using Mustache templates, but I ended up rewriting all the forms in Hiccup because it's just easier to work with.

All that said, you seem like someone that might like Enlive (https://github.com/cgrand/enlive). I'm not sure if equivalents exist in other languages, but the gist of using it for templating is that you write a plain HTML file, and run the text through Enlive along with some transforms (identified by CSS-style selectors). I've never used it for anything major, but other people have, and it seems really cool.

I enjoy using Hiccup more than any template engine I've used previously. Before I met (Clojure and) Hiccup[1], I would have said the same regarding Coffeekup[2].

But what's really amazing is when you combine Hiccup with Enlive[3]. Enlive can give you a headache when you first start working with it, but then there's an almost magical "aha!" moment, and not long after that you'll never want to look back. By "combine" I mean using Hiccup and metadata from your db (or whatever) to generate empty, logic-less views and then using Enlive to bind in your data.

Combine those steps with your own macros and HOFs, look for some choice places to memoize function calls, and now you're cooking with gas.

[1] https://github.com/weavejester/hiccup

[2] https://github.com/mauricemach/coffeekup

[3] https://github.com/cgrand/enlive

> I like even more the idea of being able to have a HTML/CSS/etc expert, who doesn't necessarily know Clojure, be able to maintain the HTML instead of me.

Check out Enlive, it solves exactly this problem. HTML/CSS is separate from Clojure code and you fill out templates and stuff via CSS style selectors. It's sweet.

https://github.com/swannodette/enlive-tutorial

https://github.com/cgrand/enlive

Btw I think you can use Enlive with Noir, even though some of the examples from Noir use Hiccup, it's not a requirement.

Isn't that just the templating library (Hiccup iirc) that Noir defaults to? Check out Enlive, it's a nice alternative that addresses your concern:

https://github.com/cgrand/enlive

https://github.com/swannodette/enlive-tutorial/

Some of my favourites -

* Enlive, a HTML scraping & templating library implemented on top of DOM parsing & state machines https://github.com/cgrand/enlive

* Core Logic, a Prolog-like logic programming library https://github.com/clojure/core.logic

* The ClojureScript compiler, a Clojure compiler that targets JavaScript https://github.com/clojure/clojurescript/blob/master/src/clj...

* Ring, a Rack/WSGI like web-app library https://github.com/mmcgrana/ring

* Midje a very powerful test framework https://github.com/marick/Midje

* Carmine, a Redis client lib in Pure Clojure https://github.com/ptaoussanis/carmine/

[EDIT] Added Midje, Ring.

That will depend very much upon your HTML developers. Some will be able to do it, a large number will not.

Even when using simple template languages I have experienced the I didn't understand those funny bits in the HTML so I have removed them far too many times.

In Clojure, Enlive (https://github.com/cgrand/enlive) is a better solution because the HTML remains as HTML.

Regarding Clojure, while compojure is popular, a compojure centric view of web programming is misguided. Compojure is part of a growing ecosystem of libraries built on top of ring[1][2].

Firstly this ecosystem is not analogous to rails or django. The closest is that Compojure is similar to Sinatra i believe.

If you are looking at getting started with web programming in Clojure you need to get familiar with ring (the http abstraction) and look at Compojure and Moustache (routing and handler composition), and Enlive[4] and Hiccup[5] (templating/html generation). Compojure and Moustache are fairly similar, but Enlive and Hiccup are extremely different. A web application will consist of ring plus one of each layer.

As has been mentioned by others in this thread, the depth, breadth and currentness of documentation for these libraries varies. David Nolen has a great tutorial for enlive[6] that i would encourage anyone looking at these libs to work through. Enlive is one of the most compelling aspects of the clojure web ecosystem at present.

These libraries provide the core pieces you would expect to see in any web framework, but a lot of the smaller details are missing. Of note there is no ORM for clojure (for obvious reasons) - If you are looking for a good SQL abstraction you should look at ClojureQL[7] - and aspects such as form generation, validation and processing is still in early days.

My day job has me building web apps with Django. I wouldnt suggest that my coworkers and I jump to clojure / ring et al yet. The breadth of libraries and out of the box stuff in django is still a huge advantage for the day to day rapid web site / web app development, however clojure's story is improving rapidly and i think that the functional model is a particularly good fit for web applications.

I cannot compare clojure's story with the other languages and frameworks mentioned.

  [1] https://github.com/mmcgrana/ring/ 
  [2] This is true of compojure 0.4 and newer. compojure existed prior to ring (with hiccup as part of it).
  [3] https://github.com/cgrand/moustache
  [4] https://github.com/cgrand/enlive
  [5] https://github.com/weavejester/hiccup
  [6] There is a link in the enlive readme
  [7] https://github.com/LauJensen/clojureql/
The Enlive system (for Clojure, see https://github.com/cgrand/enlive) does something very similar.
People using clojure can get selector based scraping using Enlive instead of JQuery [1]. It also ends up doubling as a templating library. I use it for templating on my website and I use it to scrape Hacker News, though that project the scraping is for isn't ready for launch [2].

1: https://github.com/cgrand/enlive

2: https://github.com/jColeChanged/mysite

Or don't template at all. Let your designers design documents, then you write code to modify the markup at key integration points:

https://github.com/cgrand/enlive

This has some really nice properties:

1. The only thing your devs and designers need to agree on is some basic semantic markup and tag IDs. Then they can make a full comp (complete with sample data) for their purposes. You simply rewrite that data.

2. The approach is very declarative, which makes it a lot easier to reason about what is actually being shown and what is actually changing.

3. It's amenable to all the same functional properties of the sexp->xml stuff that you see here.

Enlive's approach is a nearly 100% win for doing site templating over these sorts of sexp->xml libraries.

I still think the new gold standard for functional and extensible HTML templating is Enlive - people should look into this before coming up with variations of the same old wheel - https://github.com/cgrand/enlive