ailisp / flute

A beautiful, easilly composable HTML5 generation library in Common Lisp
64 stars 7 forks source link

Can't use `block` in `h` #9

Closed defaultxr closed 2 years ago

defaultxr commented 2 years ago

Hi. Thanks for Flute, so far it's definitely the least horrible CL HTML generation system I've used.

I'm trying to define a "template" macro for a site I'm developing. The template looks something like this:

(defmacro template ((&key title) &body body)
  `(flute:element-string
    (h (html
        (head
         (title ,title))
        (body
         (main
          (block nil
            ,@body)))))))

Unfortunately, this doesn't seem to work as expected; when I try the following in a REPL

(template (:title "test")
  (h1 "test header 1")
  (h2 "test header 2")
  (ul (li "foo")
      (li "bar")))

I get this output:

<!DOCTYPE html>
<html>
  <head><title>test</title></head>
  <body>
    <main>
      <ul>
        <li>foo</li>
        <li>bar</li>
      </ul>
    </main>
  </body>
</html>

Notice how the h1 and h2 are both missing from the output.

I've tried multiple different solutions to get this to work, including adding a few nils inside the block to "pad it out" in case it was just eating the first few items, but nothing seems to help; I can't get block to behave as expected.

Is there some way of getting this to work?

defaultxr commented 2 years ago

I realized I was thinking about this the wrong way; block of course only returns its last item. So the solution is to define template like so:

(defmacro template ((&key title) &body body)
  `(h (html
       (head
        (title ,title))
       (body
        (apply 'main
               (block nil
                 (list ,@body)))))))

This seems to work just fine. Sorry for the noise.