How to render a widget only once, regardless of external requests?

Yesod greatly simplifies web pages (created from Widgets) displayed in HTML when they are requested externally through a port warp. Why, of course, exactly where HTML is usually required.

But what if I also need a copy of this HTML for "internal purposes", created independently of the usual parameter Handler? You might think that Widgetthis is essentially just a read / write combination reading Yesodand writing a tuple of HTML, CSS and JS results. The documentation itself says: "... it's just WriterT...". Okay, but...

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

handlerdatasiteroutegwdataroute ... pah.

How do I call this and get an HTML result that is usually just sent directly 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

I just missed some function that does this, or is there a problem - maybe the widgets are actually more powerful than I thought? If so, what will be the correct type to express only WriterHTML and CSS together?

+4
source share
1 answer

I suspect you can turn Widgetto Handlerusing defaultLayoutor even widgetToPageContent, and withUrlRendererat first, and then "run" it through this tiny helper:

handler :: Handler a -> IO a
handler h = getAppSettings >>= makeFoundation >>= flip unsafeHandler h

handler . runDB "" DB.

+2

Source: https://habr.com/ru/post/1677129/


All Articles