Clojure: partly change an attribute value in Enlive

235 views Asked by At

I have this test.html file that contains:

<div class="clj-test class1 class2 col-sm-4 class3">content</div>

A want to define a template that changes only a part of an html attr value:

(deftemplate test "public/templates/test.html" []
  [:.clj-test] (enlive/set-attr :class (partly-change-attr #"col*" "col-sm-8")))

This would render:

...
<div class="clj-test class1 class2 col-sm-8 class3">content</div>
...

Thanks for your help!

2

There are 2 answers

0
leontalbot On BEST ANSWER

Just found the update-attr fn suggested by Christophe Grand in another thread:

(defn update-attr [attr f & args]
  (fn [node] (apply update-in node [:attrs attr] f args)))

Pretty cool! We can use it directly :

(enlive/deftemplate test-template "templates/test.html" []
  [:.clj-test] (update-attr :class clojure.string/replace #"col-.*?(?=\s)" "col-sm-8"))

Or build from it a more specific fn:

(defn replace-attr [attr pattern s]
      (update-attr attr clojure.string/replace pattern s))

(enlive/deftemplate test-template "templates/test.html" []
      [:.clj-test] (replace-attr :class #"col-.*?(?=\s)" "col-sm-8"))
1
RedDeckWins On

I don't know if this works for you, but if you know the class you are removing exactly you can do this.

(enlive/deftemplate test-template "templates/test.html" []
              [:.clj-test] (enlive/remove-class "col-sm-4")
              [:.clj-test] (enlive/add-class "col-sm-8"))

In the repl:

(apply str (test-template))
=> "<html><body><div class=\"class1 clj-test class2 col-sm-8 class3\">content</div></body></html>"