HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
swannodette
enlive-tutorial
Clojure2010–2017
swannodette / enlive-tutorial

enlive-tutorial

An Easy Introduction to Enlive

11Distinct people
15Mentions
0Explicit recommenders
615GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

An Easy Introduction to Enlive

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:03:16 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year15 dated mentions

Observed mentions: 2010-03-14 18:05:44 UTC to 2017-05-19 02:53:43 UTC.

02462010-01-01 00:00:00 UTC to 2011-01-01 00:00:00 UTC (exclusive): 7 mentions; 2 submissions, 5 comments20102011-01-01 00:00:00 UTC to 2012-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2012-01-01 00:00:00 UTC to 2013-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20132014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2017

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20102010-01-01 00:00:00 UTC2011-01-01 00:00:00 UTC725
20112011-01-01 00:00:00 UTC2012-01-01 00:00:00 UTC202
20122012-01-01 00:00:00 UTC2013-01-01 00:00:00 UTC312
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC202
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC000
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC000
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC000
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC101

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
An Introduction to Enlive Though Christophe Grand’s Enlive has been around for sometime now the Clojure community has been slow to embrace this useful library. I believe this is due simply to the lack of good introductory documentation based on real examples. Please let me know if you find this tutorial useful or helpful in any way. Feel free to suggest additions, corrections, and improvements (even better fork the repo and send me a patch). What You need to Know Not much. This tutorial assumes little about your exposure to Clojure. At the very least you’ll need to have the Java Virtual Machine (JVM) installed. I won’t go into great detail about Clojure’s features but I’ll try to explain any concepts which may impede your understanding of Enlive’s functionality. As the tutorials progress they will be more useful to you if you have some experience with a modern webframework that ships with a HTML templating library. If you do know Clojure the tutorials are fairly amenable to skimming. My only real assumption is that you have some experience at the command line. Enlive has many features and I can’t possibly cover them all here. Fortunately the Clojure community is vibrant and helpful. If you run into issues or have questions join the Enlive mailing list or jump on the #clojure channel on irc.freenode.net. HTML Templating There are two real camps in HTML templating. The first which almost everyone is familiar with is the PHP style template: <?php for($i = 0; $i < $len; $i++) { ?><p>Foo <?echo $i?></p><? } ?> This is of course enough to drive anyone insane and some templating solutions like the one in Django have made marginal improvements: {% for i in foo %} <p>Foo {{ i }}</p> {% endfor %} This is a bit easier on the eyes. But this isn’t very composable and you’re stuck with a limited subset of your programming language. By not composable I mean that building pages is largely a copy and paste affair even when templating solutions support inheritance. This has driven many programmers to discard templating DSLs and to generate markup directly in code. While this is fast and flexible as you now have the power of function composition, it also means that you’re putting quite a bit of distance between yourself and a designer comfortable writing HTML and CSS. There are a few existing solutions that have a novel approach to this problem such as Pure. Which brings us to Enlive. Enlive gives you the advantages of designer accessible templates (since they’re just HTML) without losing the power of function composition. As a result, your designer can create all the various widgets for your website using only HTML and CSS and you can compose your pages from any combination of their designs. Why Enlive? Enlive presents a different approach from the more popular templating solutions: Code and markup are completely separate. You get to use CSS like syntax to manipulate HTML. Template inheritance isn’t some fancy trick, it’s just function composition. You have access to the full power of Clojure to manipulate your templates (yes, macros!). When working with the standard templating solutions you generally need to answer one of two questions, either “What type of text am I going to generate?” or “What type of HTML emitting functions should I write?” In contrast, with Enlive you usually break down the problem thus: Determine which selectors match the part of the HTML document that you care about. Determine which templates and snippets you need to write to compose your pages. What We’ll Cover There are six examples in total. The first one covers grabbing the headlines and points from Hackers News. The next one shows how to make the code less redundant. The third scrapes the New York Times front page since that presents more challenges than Hacker News. The fourth example shows how to use Ring and Enlive together. The fifth example shows how things like looping are achieved without writing any code into the markup. The sixth example shows that Enlive can do all the fancy template inheritance magic you might be used to if you’re coming from Django or some other popular modern webframework. Clone This Repo The usual: git clone git://github.com/swannodette/enlive-tutorial.git Install Leiningen In order to start playing around as fast possible you should use Leiningen. It’ll take only a couple minutes to get through the instructions here. Leiningen is the easy_install (Python) and gems (Ruby) of the Clojure world. Phil Hagelberg and Co. have done a considerable amount of excellent work to make dependency management simple. I truly envy the new Clojurians who do not know the dark times before lein repl and lein swank :) Once you have Leiningen installed, switch into this repository’s directory. From there run the following command: lein deps This will install all of the dependencies required for getting through the tutorial. This might take a minute and and will probably generate a lot of output. While this may seem disconcerting, this means you’ll have a fully functioning Clojure setup without needing to bother with installing Emacs, configuring VIM, or an mucking around with an IDE. Once the the dependencies are installed enter the following command at your terminal: lein repl This will launch a Clojure REPL (Read-Eval-Print-Loop) that has the classpath set properly. Be very thankful if you don’t know what the last sentence means. Managing the classpath is one of the few real annoyances when programming Clojure and it’s largely Java’s fault. Your First Scrape with Enlive – Hacker News Enlive is fantastic for scraping the content of webpages. It allows you to scrape content by using a syntax very similar to CSS selectors. In the REPL type the following lines (note that user=> is the REPL prompt, not something you type in): user=> (load "tutorial/scrape1") nil user=> (in-ns 'tutorial.scrape1) nil tutorial.scrape1=> *base-url* "https://news.ycombinator.com/" The first line loads the file. Note tha
Read the full README on GitHub

What Hacker News says

15 sources
It sounds like your struggles are with Firebase more than the actual scraping part, so I'm not sure how useful this will be. But there's a marvelous demonstration of Clojure's ability to render and serve a scraped digest of the HackerNews homepage. https://github.com/swannodette/enlive-tutorial/blob/master/r... The final product is about 17 lines of code. Which is quite compact, sure—but if it looks like Perl, who cares? Thankfully, it looks nothing like Perl. The code is deeply intuitive and evangelizes the idea that sending an object over a network can often be defined as a composition of functions resulting in the creation of the very object that we're sending. Whether that object is an HTML document, JSON, or whatever, the alluring premise is that these can all be forged from a single bulk-concatenation of strings returned by function
Read the rest
s being unrolled in an inner-loop. It looks practically effortless. Might give you some ideas for batching those 30 GET requests. (Or maybe not—I've never used firebase before!)
In Ask HN: Is Hackernews still using the file system as database?
Yes, this is exactly why I stayed away from things like this, despite my love for Racket and Clojure, until someone above pointed out the Enlive library. It lets you use normal HTML files as your templates but requires no code in it (not even for loops!) Basically, you use CSS-style selectors to replace the contents of elements, giving you the full power of Clojure but without having to either put code in your templates or put HTML into your code. https://github.com/swannodette/enlive-tutorial/
In Show HN: I'm writing a leanpub book about Common Lisp web programming
> 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.
In Clojure-powered Startups
I recently rebuilt my site[1] in Clojure. Ring at the bottom layer (basically a given). Beyond that I'm using Moustache[2] for routing, Enlive[3] for templating and Clutch[3] to talk to CouchDB. I had previously tried with Compojure and Hiccup. The hardest parts were learning enlive and moustache. Enlive is incredibly powerful and very clever, but can be a bit overwhelming for clojure noobs. You definitely want to check out David Nolen's tutorial[5] for it. Aside from that, #clojure and the ring google group are full of wisdom. Deployment wise, I build the site with a basic leiningen[6] uberjar and run it from an ssh, background it and disown it. yeah, thats terrible, but im lazy and nobody visits my site anyhow ;) Caveat here: Clojure 1.2 has a small bug with interned keywords[7] that will knock my site over in a couple of days if i forg
Read the rest
et to start it up with the default JVM profile. the -server profile fixes the trigger issues Aside from that, I have an nginx gateway server that handles serving my media, nowww redirection and proxies all dynamic requests through to the jvm. the site itself hosts a jetty HTTP server via ring to handle all the requests. The 'hardest' part of getting started with clojure vs say Python+Django or Ruby+Rails is that there is a lack of 'get you going' magic / tools like scaffolds or djangos admin. Once you get past that though, it is a very enjoyable platform inspite of the API changes. [1]: http://brehaut.net [2]: http://github.com/cgrand/moustache [3]: http://github.com/cgrand/enlive [4]: http://github.com/ashafa/clutch [5]: http://github.com/swannodette/enlive-tutorial/ [6]: http://github.com/technomancy/leiningen [7]: http://www.assembla.com/spaces/clojure/tickets/444?comment=9...
In Ask HN: Whats the best way to start web development on lisp?
I think the point of the article is to cover the absolute basics using Ring, not advocate any particular style of development. I mean the title of the blog post does say it all. Having written a lengthy Enlive tutorial, http://github.com/swannodette/enlive-tutorial, I of course swear by it and scoff at inline html generation :D So I prefer coupling Ring+Enlive+Moustache (and tasty Aleph) myself but that would be an awful lot to cover in a single blog post now wouldn't it ;) All in good time.
In Developing and Deploying a Simple Clojure Web Application
jacquesm·Mar 17, 2010Submission

Ask HN: Why is this clojure example so slow?

Hello HN, specifically those that have some clojure experience. I've been playing around with clojure some more, specifically this tutorial: http://github.com/swannodette/enlive-tutorial I have a pretty fast box to play around with (I guess most of us do), but the tutorials run extremely slow, scraping HN takes a bit of time, I understand that, but then to list the items should be really fast. Instead it looks like the data is coming out of a 9600 baud modem. Is there any specific reason for this?
7 points · Open discussion

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.