Many thanks for all of the responses. I have no fear of the parentheses, and will likely end up with a number of wrappers like you describe, Phillip. I hadn't (yet) twigged to possibly wrapping things up in a CDATA section, but that makes sense.
Now if we just had a Racket library that shoveled snow... On Thu, Jan 4, 2018 at 2:07 PM, Philip McGrath <[email protected]> wrote: > FWIW, I use `response/xexpr` in production with a `#:preamble` of `#"<!DOCTYPE > html>\n"`, and I haven't run into problems. > > The biggest non-obvious thing, since I see you're generating a script > element, is that `response/xexpr` (and the underlying `xexpr->string`/` > write-xexpr`) properly escape < and & in body strings. This is a huge win > in preventing injection/cross-site scripting, but HTML expects inline > script and style elements not to be escaped. You can achieve this by > replacing > `(script ([type "text/javascript"]) ,(generate-some-javascript)) > with > `(script ([type "text/javascript"]) ,(make-cdata #f #f > (generate-some-javascript))) > > (If you want to go beyond that and respect the cdata-ness of the cdata, > there are tricks for both CSS and JavaScript to put the "<![CDATA[" part in > what the embedded language regards as a comment.) > > An alternative is to use `response/full` or `response/output` and take > responsibility for escaping non-trustworthy input: this is essentially what > the `web-server/templates` system does, as I understand it, though I > haven't really used that myself. > > Finally, in most of my projects of any size I end up defining some sort of > wrapper (or several) around > `response/xexpr` that handles boilerplate, headers, cookies, etc. In one > case I experimented with a custom data structure that let me combine a > fragments of HTML for the body with external CSS references to add to the > head and external JavaScript references to add to the end of the body, but > I haven't really gone farther with that. > > -Philip > > P.S.: I was very comfortable reading and writing HTML and XML-ish notation > long before I came to Racket, and I initially resisted giving up my > angle-brackets (to the extent of fiddling around with reader extensions), > but I have since become convinced that x-expressions are really a better > notation for XML than XML syntax is. > > On Thu, Jan 4, 2018 at 12:16 PM, Jay McCarthy <[email protected]> > wrote: > >> I don't think the perfect library exists, because HTML has changed >> considerably since most Racket libraries were written. >> >> I think xexpr do 90% of the job, but fails on the issues mentioned in >> that issue. I think the best option right now is either >> >> txexpr --- http://docs.racket-lang.org/txexpr/index.html >> >> or >> >> html-writing --- http://docs.racket-lang.org/html-writing/index.html >> >> But I think the perfect system is yet to be done. (I think it would >> have elements of these two, plus css-expr, for instance.) >> >> Jay >> >> >> On Thu, Jan 4, 2018 at 11:48 AM, Matt Jadud <[email protected]> wrote: >> > Hi all, >> > >> > I read through this issue: >> > >> > https://github.com/racket/racket/issues/577 >> > >> > and am in the "what is going on?" category of user when it comes to HTML >> > generation in Racket. What should I be using to generate responses from >> a >> > servlet? response/xexpr? Does that generate HTML I can use practically? >> Or, >> > doesn't it? >> > >> > I've spent a lot of time in the last few days chasing the generation of >> TOTP >> > URIs for use with apps like Authy/FreeOTP/etc. I finally realized that >> I'm >> > passing strings like >> > >> > otpauth://totp/handin:[email protected]?secret=NODOF&amp; >> issuer=handin&amp;algorithm=SHA1&amp;digits=6&amp;period=30 >> > >> > to the Javascript layer for QR encoding. This looks bad to me. >> > >> > What is the best way to generate HTML from the webserver? I don't care >> about >> > XML vs. HTML; I just want the fastest path to writing a small web >> > application that solves a problem that I have, and part of that means >> easily >> > generating HTML that does what I expect when I generate it. That is, >> > >> > (body >> > (div ((id "QRCODE"))) >> > (script ((type "text/javascript")) >> > ,(format "new >> > QRCode(document.getElementById('QRCODE'), '~a');" >> > (generate-otp-uri email secret))))) >> > >> > seems not to do what I expect, which in this case is causing some rather >> > subtle challenges to chase down. ("Why does my test for TOTP encoding >> pass >> > *here*, and generate numbers that match *this* app when I enter data by >> > hand, but fail in the same app when I read the QR code that I >> generated...") >> > >> > Pointers to relevant documentation appreciated. >> > >> > Cheers, >> > Matt >> > >> > -- >> > You received this message because you are subscribed to the Google >> Groups >> > "Racket Users" group. >> > To unsubscribe from this group and stop receiving emails from it, send >> an >> > email to [email protected]. >> > For more options, visit https://groups.google.com/d/optout. >> >> >> >> -- >> -=[ Jay McCarthy http://jeapostrophe.github.io ]=- >> -=[ Associate Professor PLT @ CS @ UMass Lowell ]=- >> -=[ Moses 1:33: And worlds without number have I created; ]=- >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

