Functional version of `with-html`?
Closed this issue · 5 comments
I have a bunch of methods that produce HTML s-expressions for the specialized classes, e.g.
(defmethod object-expression ((progress-bar progress-bar))
`(:div :class "progress-bar-base"
(:div :class "progress-bar-fill"
:id ,(id progress-bar)
;; empty string to force markup to make closing :div tag
"")))
Then at the call site, I can do
(eval `(spinneret:with-html-string
,(object-expression element)))
but obviously the eval
is not ideal here.
If spinneret:with-html-string
were not a macro, that would not be a problem. Are we missing a functional version? Or is there a better way around this problem?
Normally I just write functions/methods using with-html
, and let the (dynamically) surrounding with-html-string
capture their output into a string.
I'm open to the possibility of adding an interpreter (it wouldn't be that hard given that we already support dynamic tags and attributes) but I don't see what's being done here that wouldn't work if the methods were writing to *html*
.
A use case were the current macros don't seem to suffice: the HTML rendering of a tree.
A walker usually accepts a "collector" function as argument. This function takes 2 argument: the current node and the further results. But we can't spinneret:with-html
here because it returns nil and we would lose the tree structure upon building the result.
Does that make sense?
If spinneret had a function that accepts s-exp, this problem would have a trivial solution.
I've added an experimental interpreter in the interpret-html-tree
branch. This exports a function, interpret-html-tree
, that interprets a subset of Spinneret syntax (building on existing support for dynamic tags and attributes).
If you want to give it a try and tell me how it works for you I can merge it.
I've tested and it seems to work perfectly, thanks!