2017-05-14 2 views
4

Yesod macht es sehr einfach, Webseiten (aufgebaut von Widget s) in HTML zu rendern, wenn sie extern über den Port warp angefordert werden. Warum, das ist natürlich genau wo wir in der Regel brauchen die HTML.Wie kann ein Widget unabhängig von externen Anforderungen nur einmal gerendert werden?

Aber was, wenn ich auch eine Kopie dieses HTML für "interne Zwecke" brauche, unabhängig von der üblichen Handler Einstellung erzeugt? Sie würden denken, dass Widget im Wesentlichen nur eine Leser/Schreiber-Kombination ist, lesen Sie eine Yesod und schreiben ein Tupel von HTML, CSS und JS-Ergebnissen. The documentation itself sagt "... das ist einfach ein WriterT ...". Ok, aber ...

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

handlerdatasiteroutegwdataroute ... igitt.

Wie rufe ich dieses und im Ergebnis HTML erhalten, die normalerweise nur direkt an den Client gesendet werden würde, ohne tatsächlich das Widget in jedem Handler Einbettung?

Also, ich möchte im Grunde

runWidget :: Widget -> MyYesod -> IO Html 

heißt

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

Bin ich eine Funktion, nur fehlt das dies tut, oder gibt es ein Problem - vielleicht Widgets tatsächlich mächtiger sind, als ich dachte? Wenn ja, was wäre der richtige Typ, um nur Writer von HTML und CSS zusammen auszudrücken?

Antwort

2

Ich vermute, Sie Widget in Handler mit defaultLayout oder sogar widgetToPageContent und withUrlRenderer zuerst drehen kann, und „laufen“ es dann mit diesem kleinen Helfer:

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

Sie auch handler . runDB verwenden können, um „run“ DB Aktionen auf diese Weise.

+0

'do {html <- defaultLayout Widget; sendByEmail Empfänger html} ' – Jakub

Verwandte Themen