Embeddable HTML templating engine for Common Lisp with JSX-like syntax
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" ></welcome> 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))))
Copyright (c) 2018 Eitaro Fukamachi
Licensed under the BSD 2-Clause License.