Hiccup in pure Clojure
(require '[huff2.core :as h])
[:. {:style {:font-size 30}}]
🎨:div#id.c
or :div.c#id
both work (not the case for hiccup/hiccup
)lambdaisland/hiccup
) 👵[:<> [:li.a] [:li.b]]
🙂(list [:li.a] [:li.b])
🙃:hiccup/raw-html
: let users bypass html compilation, now with raw-strings. 📦[:. {:color :red}]
💥Parse tags for id and class (in any order).
(h/html [:div.hello#world "!"])
;; => <div class="hello" id="world">!</div>
(println (h/html [:div.left-aligned>p#user-parent>span {:id "user-name"} "Jason"]))
;=> <div class="left-aligned"><p id="user-parent"><span id="user-name">Jason</span></p></div>
(h/html [:<> [:div "d"] [:<> [:<> [:span "s"]]]])
;; =>
<div>d</div><span>s</span>
This is useful for returning multiple elements from a function:
(defn twins [x] [:<>
[:div.a x]
[:div.b x]])
(h/html [:span.parent [twins "elements"]])
;;=>
<span class="parent">
<div class="a">elements</div>
<div class="b">elements</div>
</span>
Nest and combine them with lists to better convey intent to expand:
(h/html
[:ol
[:<> (for [x [1 2]]
[:li>p.green {:id (str "id-" x)} x])]])
;;=>
<ol>
<li>
<p id=\"id-1\" class=\"green\">1</p>
</li>
<li>
<p id=\"id-2\" class=\"green\">2</p>
</li>
</ol>
(h/html [:div {:style {:border "1px red solid"
:background-color "#ff00ff"}}])
;; => <div style="background-color:#ff00ff;border:1px red solid;"></div>
(h/html [:. {:style {:width 3}}])
;;=> <div style=\"width:3px;\"></div>
This is nice if you want to e.g. render markdown in the middle of your hiccup. Note: We disable this by default and it must be manually enabled in the call to html
or page
,
(h/html [:hiccup/raw-html "<div>raw</div>"])
;; =Throws=> :hiccup/raw-html is not allowed. Maybe you meant to set allow-raw to true?
(h/html {:allow-raw true} [:hiccup/raw-html "<div>raw</div>"])
;;=> <div>raw</div>
Another nice-to-have is to disallow raw html in un-trusted data getting passed into to the compiler, but being able to do that as a dev.
(h/html [:div [:hiccup/raw-html (h/raw-string "<!-- oops.")]])
;; => <div><!-- oops.</div>
[More Info]
Write a function that returns hiccup, and call it from the first position of a vector, like in reagent.
(defn str-info [s]
[:div.info
[:span (apply str (reverse s))]
[:pre.len "Length: " (count s)]])
(h/html [str-info "hello"])
;; =>
<div class="info">
<span>olleh</span>
<pre class="len">Length: 5</pre>
</div>
(h/html [:div {:style {:width (* 5 2)}}])
;;=> <div style="width:10px;"></div>
We now offer some super-deep customization of the hiccup grammar.
With this power, you can write new tags that can parse (and validate) their inputs.
Let's say you really need a tag to count its children, and put that into the final html.
(def my-schema (h2e/add-schema-branch h/hiccup-schema :my/child-counter-tag))
(defmethod h/emit :my/child-counter-tag [append! [_ [_ values]] opts]
(append! "I have " (count values) " children."))
append!
takes strings and will append them internally during html generation.
;; call:
(h/html (custom-fxns! my-schema)
[:div>h1 [:my/child-counter-tag "one" "two" "three"]])
;; => <div><h1>I have 3 children.</h1></div>
This will be a little faster, and you should prefer it if your schema isnt dynamic.
;; build:
(let [my-fxns (custom-fxns! my-schema)]
(def my-html (fn my-html [hic] (h/html my-fxns))))
(my-html [:div>h1 [:my/child-counter-tag "one" "two" "three"]])
;; => <div><h1>I have 3 children.</h1></div>
More details in the huff extension test.
Can you improve this documentation? These fine people already did:
Bryan Maass & Mykhaylo BilyanskyyEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close