Question

I am currently developing a small CMS using the wonderful Enlive as templating engine. Enlive has a macro called at that takes a node (a map) specifying the HTML snippet and an arbitrary number of tuples each consisting of a selector (a vector) and a transformation (a closure).

(at a-node
  [:a :selector] a-transformation
  [:another :selector] another-transformation
  ...)

Now I want to generate the tuples depending upon incoming data/context. I have tried a lot of different things without success. For example

(let [this (repository/u "http://example.com/ACMECorp")
      statements (repository/find-by-subject this)
      context {:depth 1}]
  `(at (snippet-for 'this 'context)
       [root] (set-attr :about (str 'this))
       ~@(loop [rules []
                st statements]
           (if-not (seq st)
             rules
             (recur (conj rules
                          `[:> (attr= :property ~(str (repository/predicate (first st))))]
                          `(content (renderit ~(repository/object (first st)) 'context)))
                    (rest st))))))

Any help is highly appreciated.

-Jochen

Was it helpful?

Solution

Clojure is a Lisp, so you can always fallback to building the code you'd want as a list, and call eval on it. I'm not 100% sure about the code you gave, but I'd guess you just want to enclose your whole syntax-quote in an eval call.

(let [this (repository/u "http://example.com/ACMECorp")
      statements (repository/find-by-subject this)
      context {:depth 1}]
  (eval `(at (snippet-for 'this 'context)
             [root] (set-attr :about (str 'this))
             ~@(loop [rules []
                      st statements]
                 (if-not (seq st)
                   rules
                   (recur (conj rules
                                `[:> (attr= :property ~(str (repository/predicate (first st))))]
                                `(content (renderit ~(repository/object (first st)) 'context)))
                          (rest st)))))))

OTHER TIPS

Not sure if they are interchangeable, but take a look at the at* function. Seems to me that your problem is at being a macro.

EDIT: They're not. Call it like this:

(at* a-node
  [[:a :selector] a-transformation
   [:another :selector] another-transformation
   ...])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top