How to render a Widget just a single time, independent of external requests?

Viewed 80

Yesod makes it very simple to have web pages (built up from Widgets) rendered to HTML whenever they are requested externally through warp's port. Why, that is of course precisely where we usually need the HTML.

But what if I also need a copy of that HTML for “internal purposes”, generated independently of the usual Handler setting? You'd think that Widget is essentially just a reader/writer combination, reading a Yesod and writing a tuple of HTML, CSS and JS results. The documentation itself says “...this is simply a WriterT...”. Ok, but...

newtype WidgetT site m a = WidgetT
    { unWidgetT :: HandlerData site (MonadRoute m) -> m (a, GWData (Route site))
    }

handlerdatasiteroutegwdataroute... ugh.

How do I invoke this and get at the result HTML that would normally just be sent straight to the client, without actually embedding the widget in any Handler?

So, I basically want

runWidget :: Widget -> MyYesod -> IO Html

i.e.

             WidgetT MyYesod IO () -> MyYesod -> IO Html

Am I just missing some function that does this, or is there a problem – perhaps widgets are actually more powerful than I thought? If so, what would be the correct type to express just Writer of HTML and CSS together?

1 Answers
Related