feature request: spinneret
Hi could this library support spinneret?
If so, what would be required?
Hi. Would require a Spinneret renderer.
The equivalent of this file: https://github.com/mmontone/cl-forms/blob/master/src/renderer/who.lisp, but using Spinneret instead of cl-who.
I think you may be able to mix both cl-who and spinneret,though. If both libraries write to the same output stream..
I have an example of using cl-who renderer and spinneret at the same time:
(forms:defform my-form ()
((input :string)))
(let ((form (forms:get-form 'my-form)))
(with-output-to-string (*html*)
(spinneret:with-html
(let ((cl-forms.who:*html* *html*)
(spinneret:*html* *html*))
(:h1 "This is my form")
(forms:with-form-renderer :who
(forms:render-form form))
(:ul
(loop for i from 1 to 10
do (:li (princ-to-string i))))))))
There may be a cleaner way of connecting things. Feels like a macro should be implemented there ..
But this works. cl-who html stream, cl-forms.who:*html* and spinneret:*html* are all bound to the same output stream.
a problem i encountered with the above approach is that it doesn't work with spinneret:with-html-string, as that macro binds its own, new (i think) spinneret:*html*.
(with-output-to-string (*html*)
(let ((forms.who:*html* *html*)
(spinneret:*html* *html*))
(spinneret:with-html-string
(:title "new agent")
(:br))))
returns "".
and the problem with that is that with-html-string can be used by intermediate functions/macros, like pages/grids.
not sure if there is any way to get around this? i tried binding everything to spinneret:*html* as the stream but it also didn't work.
i find myself with a little frankenstein html when combining cl-forms and spinneret.
basic example, based on the above method to combine them:
(forms:defform create-agent (:action "/create")
((name :string :value "")
(age :string :value "")
(location :string :value "")
(submit :submit :label "Submit")))
(let ((form (forms::find-form 'create-agent)))
(with-output-to-string (*html*)
(let ((forms.who:*html* *html*)
(spinneret:*html* *html*))
(spinneret:with-html
(:doctype)
(:html
(:body
(:h1 "new agent")
(:main
(forms:with-form-renderer :who
(forms:render-form form)))))))))
output (with junk </form> after </form>):
<!DOCTYPE html>
<html lang=en>
<body>
<h1>new agent</h1>
<main><form id='G4521' action='/agents' method='POST'><div><label>Name</label><input type=\"text\" name=\"name\" value=\"\"></input></div><div><label>Age</label><input type=\"text\" name=\"age\" value=\"\"></input></div><div><label>Location</label><input type=\"text\" name=\"location\" value=\"\"></input></div><div><input type='submit' value='Submit' /></div></form>
</form>
</main>
</body>
</html>
it's possible to unescape the last form by wrapping the call to forms:render-form in spinneret's :raw, but then there are two closing form tags in the html.
Not ideal, but you can return NIL to prevent Spinneret from rendering that last form tag:
(let ((form (forms::find-form 'create-agent)))
(with-output-to-string (*html*)
(let ((forms.who:*html* *html*)
(spinneret:*html* *html*))
(spinneret:with-html
(:doctype)
(:html
(:body
(:h1 "new agent")
(:main
(forms:with-form-renderer :who
(forms:render-form form)
nil))))))))