Awesome
HSX
HSX (Hypertext S-expression) is a simple and powerful HTML (Living Standard) generation library for Common Lisp.
This project is a fork of ailisp/flute.
Warning
This software is still in ALPHA quality. The APIs are likely to change.
Please check the release notes for updates.
Getting Started
Basic Usage
Use the hsx
macro to create HTML elements. Attributes are specified using a property list after the element name, and child elements are nested directly inside.
(hsx
(div :id "example" :class "container"
(h1 "Welcome to HSX")
(p "This is an example paragraph.")))
This generates:
<div id="example" class="container">
<h1>Welcome to HSX</h1>
<p>This is an example paragraph.</p>
</div>
To convert an HSX object into an HTML string, use the render-to-string
function:
(render-to-string
(hsx ...))
Embedding Content
HSX allows you to embed Common Lisp forms directly within your HTML structure.
When working with HSX elements inside embedded Lisp forms, you should use the hsx
macro again.
(hsx
(div
(p :id (format nil "id-~a" (random 100)))
(ul
(loop
:for i :from 1 :to 5 :collect
(hsx (li (format nil "Item ~a" i)))))
(if (> (random 10) 5)
(hsx (p "Condition met!"))
(hsx (p "Condition not met!")))))
This might generate:
<div>
<p id="id-42"></p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
</ul>
<p>Condition not met!</p>
</div>
Using Fragments
To group multiple elements without adding an extra wrapper, use the fragment <>
.
(hsx
(<>
(h1 "Grouped Elements")
(p "First paragraph.")
(p "Second paragraph.")))
This generates:
<h1>Grouped Elements</h1>
<p>First paragraph.</p>
<p>Second paragraph.</p>
Creating Components
You can define reusable components using the defcomp
macro. Component names must begin with a tilde (~
). Properties should be declared using &key
, &rest
, or both. The body must return an HSX element.
(defcomp ~card (&key title children)
(hsx
(div :class "card"
(h1 title)
children)))
Alternatively, you can use a property list:
(defcomp ~card (&rest props)
(hsx
(div :class "card"
(h1 (getf props :title))
(getf props :children))))
Usage example:
(hsx
(~card :title "Card Title"
(p "This is a card component.")))
Generates:
<div class="card">
<h1>Card Title</h1>
<p>This is a card component.</p>
</div>
License
This project is licensed under the MIT License.
© 2024 skyizwhite
© 2018 Bo Yao
Feel free to contribute to the project and report any issues or feature requests on the GitHub repository.