12 HAML
(require koyo/haml) | package: koyo-lib |
haml is a convenience macro for generating xexprs with less boilerplate. Its syntax is inspired by haml – whence its name – but if you’ve used Clojure’s hiccup or any similar templating language (like jade or pug), then haml will feel familiar to you.
12.1 Syntax
syntax
(haml element ...+)
element = (selector maybe-attributes element ...) | (unless cond-expr e0 e ...) | (when cond-expr e0 e ...) | &html-entity-name | ,@expr | expr selector = :tag-name | .class-name | .class-name-1.class-name-2.class-name-n#id | :tag-name.class-name | :tag-name.class-name#id maybe-attributes =
| ([:attribute-name maybe-expr] ...)
Literal numbers and strings are returned unmodified:
> (haml 1) 1
> (haml "hello") "hello"
Identifiers that start with an & character are converted to symbols with the initial & removed:
> (haml &mdash) 'mdash
Other identifiers are evaluated from the enclosing environment:
> (let ([a-symbol 'mdash]) (haml a-symbol)) 'mdash
Element tags start with a colon:
> (haml (:h1 "Hello World")) '(h1 () "Hello World")
Id and class attributes can be attached to a tag via a shorthand syntax:
> (haml (:h1.title#main-title "Hello World")) '(h1 ((id "main-title") (class "title")) "Hello World")
Tag names are optional if a class name is provided, in which case the tag defaults to div:
> (haml (.content (:h1.title "Hello World"))) '(div ((class "content")) (h1 ((class "title")) "Hello World"))
Repeated attributes are concatenated into a single value:
> (haml (.content (:h1.title ([:class "hello"] [:data-example "1"] [:data-example "2"]) "Hello World"))) '(div ((class "content")) (h1 ((class "title hello") (data-example "1 2")) "Hello World"))
Lists of elements can be spliced in using the ,@e syntax:
> (haml (.content (:ul.items ,@(for/list ([it '("a" "b" "c")]) `(li ,it))))) '(div ((class "content")) (ul ((class "items")) (li "a") (li "b") (li "c")))
Expressions that don’t parse as elements are evaluated in place at runtime:
> (define (say-hi name) (format "Hi, ~a!" name))
> (haml (:h1 (say-hi "Bogdan"))) '(h1 () "Hi, Bogdan!")
The when and unless forms are special-cased so that they automatically splice their result, if any, into the enclosing expression:
> (for ([v '(#t #f)]) (println (haml (:h1 (when v "a") "title"))))
'(h1 () "a" "title")
'(h1 () "title")
Passing multiple elements to the haml macro produces a list of xexpr?s:
> (haml (:li "a") (:li "b")) '((li () "a") (li () "b"))
Changed in version 0.10 of package koyo-lib: when, unless and unquote-splicing are
now recognized by binding. The @-style splicing syntax is no
longer supported.
Changed in version 0.17: Element attributes may now begin with an @ symbol.
12.2 Templates
(require koyo/haml-template) | package: koyo-lib |
HAML templates let you define templatized versions of the haml form.
syntax
(define-haml-template id element)
> (define-haml-template container (.container (slot)))
> (container (:strong "child 1") (:strong "child 2")) '(div ((class "container")) (strong () "child 1") (strong () "child 2"))
Added in version 0.22 of package koyo-lib.
syntax
(slot)