Simple and powerful HTML generation library
Find a file
2024-12-17 16:14:46 +09:00
.github/workflows Rename CI to test 2024-06-01 20:16:53 +09:00
src Modify the wording 2024-12-17 16:14:46 +09:00
tests Fix defcomp to detect components in HSX 2024-12-13 01:33:01 +09:00
.gitignore Add qlfile 2024-02-03 14:55:44 +09:00
hsx-test.asd Rename hsx/hsx to hsx/dsl 2024-10-03 11:00:19 +09:00
hsx.asd Update system version to v0.4.0 2024-12-13 01:37:10 +09:00
LICENSE Update license 2024-02-09 20:21:04 +09:00
qlfile Use cl-str instead 2024-10-04 08:44:27 +09:00
qlfile.lock Use cl-str instead 2024-10-04 08:44:27 +09:00
README.md Update README 2024-12-13 01:35:31 +09:00

HSX

HSX (Hypertext S-expression) is a simple yet powerful HTML5 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.