Skip to content

Instantly share code, notes, and snippets.

@mjwillson
Last active December 17, 2015 12:49
Show Gist options
  • Save mjwillson/5612819 to your computer and use it in GitHub Desktop.
Save mjwillson/5612819 to your computer and use it in GitHub Desktop.
Proof of concept: S-expressions for HTML templating in clojure
(defprotocol ToHtml
(to-html [x]))
(extend-protocol ToHtml
String
(to-html [s]
(clojure.string/escape s {\< "&lt;" \> "&gt;" \" "&quot;" \& "&amp;"}))
clojure.lang.IPersistentMap
(to-html [attrs]
(clojure.string/join
" " (for [[k v] attrs]
(str (name k) "=\"" (to-html (str v)) "\""))))
clojure.lang.ISeq
(to-html [[tag attrs-or-more & more]]
(if (map? attrs-or-more)
(str
"<" tag " " (to-html attrs-or-more) ">"
(apply str (map to-html more))
"</" tag ">")
(str "<" tag ">"
(apply str (map to-html (cons attrs-or-more more)))
"</" tag ">"))))
(to-html (div {:class "foo" :id "bar"}
(h1 "Hello")
(p "Some text" (i "Italic"))))
(println (to-html '(div {:class "foo" :id "bar"}
(h1 "Hello")
(p "Some text" (i "Italic")))))
; => <div class="foo" id="bar"><h1>Hello</h1><p>Some text<i>Italic</i></p></div>
;; Then in combination with https://github.com/brandonbloom/backtick, you can do templating via syntax-quote:
(template (ul {:class "foo-list"} ~@items))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment