Embeddable HTML templating engine with JSX-like syntax.
(ql:quickload '(:lsx :local-time))
(lsx:enable-lsx-syntax)
<br/>
;=> #<LSX/HTML:ELEMENT br {1003F98BF3}>
(lsx:render-object <br/> t)
;-> <br>
;=> NIL
(lsx:render-object <a href="/hello">Say Hello</a> t)
;-> <a href="/hello">Say Hello</a>
;=> NIL
;;
;; Embed Lisp code in {}
(lsx:render-object <a href="/hello">Say Hello at {(local-time:now)}</a> t)
;-> <a href="/hello">Say Hello at 2018-09-14T05:04:55.009102+09:00</a>
;=> NIL
(lsx:deftag welcome (&key name)
<h1>{name}</h1>)
<welcome name="fukamachi"></welcome>
;=> #<WELCOME {10028D74D3}>
(lsx:render-object <welcome name="fukamachi" /> t)
;-> <h1>fukamachi</h1>
;=> NIL
(lsx:deftemplate default-layout ()
(title body)
(:render
<html>
<head>
<title>{title}</title>
</head>
<body>
{body}
</body>
</html>))
(lsx:deftemplate index-page (default-layout)
()
(:default-initargs
:title "Index"
:body <h1>Welcome</h1>))
(lsx:render 'index-page)
;=> "<!DOCTYPE html>
; <html>
; <head>
; <title>Index</title>
; </head>
; <body>
; <h1>Welcome</h1>
; </body>
; </html>
; "
;; example.lsx
(lambda (&key (name "Guest"))
<html>
<head>
<title>Welcome {name}</title>
</head>
<body>
<div id="main"><h1>Hello</h1><p><a href="/entries">Show Entries</a></p></div>
</body>
</html>)
(lsx:read-lsx-file #P"example.lsx")
;=> #<FUNCTION (LAMBDA (&KEY :NAME) :IN "~/Programs/lib/lsx/example.lsx") {1005E72B5B}>
(lsx:render-object (funcall * :name "fukamachi") t)
;-> <!DOCTYPE html>
; <html>
; <head>
; <title>Welcome fukamachi</title>
; </head>
; <body>
; <div id="main"><h1>Hello</h1><p><a href="/entries">Show Entries</a></p></div>
; </body>
; </html>
;=> NIL
LSX syntax is implemented as reader macro. It's able to see how it's expanded with quoting.
'<br/>
;=> (LSX/TAG:H 'BR (LIST))
'<a href="/hello">Say Hello</a>
;=> (LSX/TAG:H 'A (LIST (CONS "href" "/hello")) (LIST "Say Hello"))
'<a href="/hello">Say Hello at {(local-time:now)}</a>
;=> (LSX/TAG:H 'A (LIST (CONS "href" "/hello")) (LIST "Say Hello at " (LAMBDA () (LOCAL-TIME:NOW))))
h
is a function to make an element. It takes a single required argument, a tag-name
as a string, and 2 optional arguments, attributes as an association list and children as a list of elements.
;; Same as <br/>
(lsx:h "br")
;=> #<LSX/HTML:ELEMENT br {10033183D3}>
(lsx:h "a" '(("href" . "/hello")) '("Say Hello"))
;=> #<LSX/HTML:ELEMENT a {100331D823}>
(lsx:h "a" '(("href" . "/hello")) (list "Say Hello at " (lambda () (local-time:now))))
- Eitaro Fukamachi (e.arrows@gmail.com)
Copyright (c) 2018 Eitaro Fukamachi
Licensed under the BSD 2-Clause License.