Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/borkdude/html
Html generation library inspired by squint's html tag
https://github.com/borkdude/html
clojure clojurescript hiccup html
Last synced: 4 months ago
JSON representation
Html generation library inspired by squint's html tag
- Host: GitHub
- URL: https://github.com/borkdude/html
- Owner: borkdude
- License: mit
- Created: 2024-05-26T15:57:31.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2024-06-05T15:41:27.000Z (8 months ago)
- Last Synced: 2024-09-29T17:22:11.438Z (4 months ago)
- Topics: clojure, clojurescript, hiccup, html
- Language: Clojure
- Homepage:
- Size: 50.8 KB
- Stars: 48
- Watchers: 2
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# html
Produce HTML from hiccup in Clojure and ClojureScript.
[![Clojars Project](https://img.shields.io/clojars/v/io.github.borkdude/html.svg)](https://clojars.org/io.github.borkdude/html)
## Rationale
[Squint](https://github.com/squint-cljs/squint) and
[cherry](https://github.com/squint-cljs/cherry) support HTML generation as
built-in functionality. Some people wanted this functionality in JVM Clojure and
ClojureScript as well. That is what this library offers.Benefits over some (but definitely not all) hiccup libraries may be:
- Generation of HTML is done at compile time, hiccup vectors are never inspected at runtime
- The generated code is small and easy to understand
- The library itself is small (currently around 100 lines of code)
- The library works both in Clojure and ClojureScriptDrawbacks of this library:
- Less dynamic compared to other hiccup libraries (this can also seen as a benefit when it comes to security and performance)
- New and thus not as mature and battle tested as other libraries. Issues + PRs welcome though
- This library only outputs HTML5In this README, all example results are written as strings. In reality they are
a `borkdude.html.Html` object which just contains a string. This is done to
prevent issues with double-encoding.## Examples
``` clojure
(require '[borkdude.html :refer [html]])(let [name "Michiel"]
(html [:div {:color :blue :style {:color :blue}}
[:p "Hello there " name
[:ul
[:li 1]
(map (fn [i]
(html [:li i]))
[2 3 4])]]]))
;;=>
""Hello there Michiel
- 1
- 2
- 3
- 4
```## Passing props
This library doesn't support dynamic creation of attributes in the same way that
some hiccup libraries do. Rather, you have to use the special `:&` property to
pass any dynamic properties, reminiscent of the JSX spread operator:``` clojure
"
(let [m {:style {:color :blue} :class "foo"}]
(html [:div {:class "bar" :& m}]))
;;=> "
```Any static properties, like `:class "bar"` above function as a default which
will be overridden by the dynamic map `m`.## Fragment
A fragment can be written in a similar way as JSX with `:<>` as the tag:
``` clojure
(html [:div [:<> "Hello " "world"]]) ;;=>Hello world
```## Unsafe
Unsafe HTML (which won't be HTML-escaped) can be written with:
``` clojure
(html [:$ "]) ;;=> ""
```## Child components
Just use function calls for child components:
``` clojure
(defn child-component [{:keys [name]}]
(html [:div "Hello " name]))(defn App []
(html
[:div
[:div {:color :blue}]
(child-component {:name "Michiel"})]))(App) ;=> "
"
Hello Michiel
```## Child seqs
To render a sequence of child elements, use `html` to render the child element as well:
``` clojure
(html
[:ul
[:li 1]
(map (fn [i] (html [:li i])) [2 3])])
;;=> "
- 1
- 2
- 3
```
## Performance
Despite the relative simplicity of this library, performance is quite good. Here
is an informal benchmark against `hiccup/hiccup`:
``` clojure
(comment
(defn ul []
(html [:ul [:li 1]
(map (fn [i]
(html [:li i]))
[2 3])]))
(time (dotimes [_ 10000000] (ul))) ;; ~3600ms
(defn ul-hiccup []
(hiccup2.core/html [:ul [:li 1]
(map (fn [i]
[:li i])
[2 3])]))
(time (dotimes [_ 10000000] (ul-hiccup))) ;; ~5500ms
)
```
Note that in `hiccup/hiccup`s case, when we wrap the `[:li i]` element within a
call to `hiccup2.core/html` as well, performance becomes similar as `html` since
it can do a similar compile-time optimization.
## Data reader
To install the `#html` reader, add the following to `data_readers.cljc`:
``` clojure
{html borkdude.html/html-reader}
```
Then you can write:
``` clojure
#html [:div "Hello"]
```
Note that these data readers aren't enabled by default since it's not recommended
to use unqualified data readers for libraries since this can be a source of
conflicts.
## Complete HTML5 document
When using `html`, this library outputs HTML5. So `[:br]` compiles to `
`
without a closing tag. Here is an example of how to to output a complete HTML5
document:
``` clojure
(html
[:<>
[:$ ""]
[:html {:lang "en"}
[:head
[:meta {:charset "utf-8"}]
[:title "Hi"]]
[:body
[:div "ok"]
[:p
"yes"
[:br]]]]])
```
## License
MIT, see `LICENSE`