TAGS :Viewed: 1 - Published at: a few seconds ago

[ Enlive snippet in template produces lazy sequence ]

Visiting localhost:3001/test results in the following HTML:



Clojure Code:

(ns notebook.handler
  (:require [compojure.core :refer :all]
            [compojure.handler :as handler]
            [compojure.route :as route]
            [net.cgrand.enlive-html :as html]))

(html/defsnippet welcome
      (html/html [:h1])              ; html snippet
      [:h1]                          ; selector
      [username]                     ; arguments
      [:h1] (html/content username)) ; substitution

(html/deftemplate home-page "templates/base.html"
   [:body] (html/html-content (welcome username)))

(defroutes app-routes
  (GET "/test" [] (home-page "oru"))
  (route/resources "/")
  (route/not-found "Not Found"))

(def app
   (handler/site app-routes))

It looks like I'm not using templates correctly and/or screwing up laziness somewhere. I've tried placing doall in a few places hoping it'd resolve the laziness but no dice.

A debugging attempt:

(welcome "oru")
=> ({:tag :h1, :attrs {}, :content ("oru")})

(html/emit* (welcome "oru"))
=> ("<" "h1" ">" "oru" "</" "h1" ">")

So far so good...

(home-page "oru")
=> ("<" "html" ">" "\n  " "<" "head" ">" "\n  " "</" "head" ">" "\n  " "<" "body" ">" "clojure.lang.LazySeq@27237276" "</" "body" ">" "\n\n" "</" "html" ">")

Bam! "clojure.lang.LazySeq@27237276", the heck is this doing here?

Answer 1

You want to use content, not html-content, since snippets produce a sequence of nodes. html-content expects a string of literal HTML content, and is likely just calling str on its argument (in this case the lazy sequence that is the output of your snippet).