lsx
2022-02-20
Embeddable HTML templating engine with JSX-like syntax
LSX
Embeddable HTML templating engine with JSX-like syntax.
Usage
(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
Defining custom tags
(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
Defining templates
(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> ; "
Loading from file
;; 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
How it works
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))))
See Also
Author
- Eitaro Fukamachi (e.arrows@gmail.com)
Copyright
Copyright (c) 2018 Eitaro Fukamachi
License
Licensed under the BSD 2-Clause License.