What is the best way to do multiple passes over a template in enlive

46 views Asked by At

I want to take an fetched html page and create an enlive template from it

(-> (fetch) ; function returns clj-http.client/get
    (:body)
    (clojure.java.io/reader)
    (html/html-resource) ; enlive
    (swap-header)
    (swap-body-tag))

My two swap fns look like this

(defn swap-header [body]
  (as-> (html/deftemplate temp body [content] [:body] (html/content content)) x
        (apply str (x "testing"))))

(defn swap-body-tag [body]
  (as-> (html/deftemplate temp body [disabled] [:body] (html/set-attr :disabled disabled)) x
        (apply str (x "yo-123"))))

So the dilemma is that I can comment out either of these two swaps from the fetch return pipeline and it works fine. Trying to (in either order) gives a fail. I believe the result of a applied template is the wrong format to make another template from it but can't quite get where i need to be.

The Error I get when i chain them is HTML resource not found.

Edited to use more filled out code and remove comp

Update I copied a function from https://stackoverflow.com/a/38284236/736368 to make a string a reader. which seems to get this working. Is this seem like a good approach from a performance perspective?

(->> ctx
    (:request)
    (fetch)
    (:body)
    (clojure.java.io/reader)
    (html/html-resource)
    (swap-body-tag)
    (apply str)           ; new 
    (string->stream)      ; new
    (swap-header))
1

There are 1 answers

1
Alan Thompson On

Do you have the functions reversed in the call to comp? They are applied from the right first. Perhaps:

((comp swap-urls clean-footer clean-header) parsed)

which is like this:

(-> parsed
  clean-header
  clean-footer
  swap-urls)

I tend to like the thread-first macro better than comp, since I think it is clearer.