.github/workflows | ||
src | ||
tests | ||
.gitignore | ||
hsx-test.asd | ||
hsx.asd | ||
LICENSE | ||
qlfile | ||
qlfile.lock | ||
README.md |
HSX
⚠️ This project is a work in progress. Roadmap
HSX (Hypertext S-expression) is a straightforward HTML5 generation library for Common Lisp.
This project is a fork of flute, originally created by Bo Yao.
Usage
With the hsx
macro, you can construct HTML using S-expressions.
The role of the hsx
macro is to detect symbols of built-in elements and import the corresponding functions on demand. It is not needed when invoking user components defined with the defcomp
macro.
The property list (inline form is also available) following the element name is interpreted as attributes, while the remaining elements are interpreted as child elements.
When a property is given a boolean value:
t
results in the key being displayed without a value.nil
results in the property not being displayed at all.- Any other type of value results in the key-value pair being displayed.
(hsx
(div :id "greeting" :class "flex"
(h1 "Hello World")
(p
"This is"
(strong '(:class "red")
"an example!"))))
This code generates the following HTML:
<div id="greeting" class="flex">
<h1>Hello World</h1>
<p>
This is
<strong class="red">an example!</strong>
</p>
</div>
HSX elements are essentially functions, allowing you to compose them freely and embed Common Lisp code within them.
(hsx
(div
(p :id (+ 1 1))
(ul
(loop
:for i :from 1 :to 3
:collect (li (format nil "item~a" i))))
(if t
(p "true")
(p "false"))))
This generates:
<div>
<p id="2"></p>
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
<p>true</p>
</div>
The fragment <>
allows you to group multiple elements without introducing additional wrappers.
(hsx
(<>
(h1 "Title")
(p "This is a paragraph.")
(p "This is another paragraph.")))
This generates:
<h1>Title</h1>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
You can create HSX components using the defcomp
macro. Components are essentially functions that accept keyword arguments, a property list, or both.
The children
property accepts the children of a component.
(defcomp card (&key title children)
(hsx
(div
(h1 title)
children)))
or
(defcomp card (&rest props)
(hsx
(div
(h1 (getf props :title))
(getf props :children))))
This can then be used as follows:
(hsx
(card :title "card1"
(p "Lorem ipsum...")))
Which generates:
<div>
<h1>card1</h1>
<p>Lorem ipsum...</p>
</div>
To output HSX as an HTML string, use the render-to-string
method.
(render-to-string (hsx ...))
License
This project is licensed under the terms of the MIT license.
© 2024 skyizwhite
© 2018 Bo Yao