ruricolist / spinneret

Common Lisp HTML5 generator
MIT License
369 stars 26 forks source link

Feature request: runtime generation of tags #16

Closed fiddlerwoaroof closed 7 years ago

fiddlerwoaroof commented 7 years ago

I'd like to be able to leave a tag unfilled at compile time and then generate it at run time. For example, I'd like to be able to automatically create the appropriate h1-h6 tag based on the value of a dynamic variable, something like:

(defvar *nesting-level* 1)
(spinneret:deftag section (...)
  `(:section (spinneret:dynamic-tag ((format nil "H~d" *nesting-level*))
                    "The heading")
     (let ((*nesting-level* (1+ *nesting-level*))
       ,@body))
(spinneret:with-html
  (section (section "test")))

should generate something like

<section>
  <h1>The heading</h1>
  <section>
    <h1>The heading</h1>
    test
  </section>
</section>

I can do this right now by doing something like

(format spinneret:*html* "<H~d>~a</H~@*~d>" *nesting-level* "The heading")

But that seems a bit inelegant: (a) it seems to be doing stuff at a lower-level than the rest of the surrounding code and (b) it doesn't interact well with the pretty printer.

ruricolist commented 7 years ago

To be clear, do you actually need full support for dynamic tags, or would a specific solution to the problem of nesting headings be acceptable?

fiddlerwoaroof commented 7 years ago

That would work too for my current purposes, as long as the heading level is determined at run time and not before.

ruricolist commented 7 years ago

This is in Spinneret now. There is support for dynamic tags (using the :tag pseudo-tag) and a specific pseudo-tag for this particular use case (:h*). The README has the details.

fiddlerwoaroof commented 7 years ago

Great, thanks!