Widgets in Yesod are a way to add some nice features – like order independence – to created parts of page. That’s because Widgets
are more semantic elements than a set of tags – they also contain some information about tag location – for example if it should be inserted in the header or body of the page. For example, let’s assume we want to add a button that will redirect from each detailed project page to the list of all projects.
To do this, we’re gonna create a Hamlet template (in templates/back-to-projects.hamlet
) for the widget first. It’ll contain the following code:
Then let’s create a Cassius template (templates/back-to-projects.cassius
) for styles:
And in the end let’s use these templates in our Handler/Project.hs
:
renderPage :: (Int, Text) -> Widget renderPage projectEntry = do setTitle $ ("Project " ++ projectTitle) $(widgetFile "project") $(widgetFile "back-to-projects") where projectTitle = (toHtml projectId) ++ (toHtml projectName) projectName = snd projectEntry projectId = fst projectEntry
As a result, we get a nice button below the description of the project – this way we can add widget after widget to the page. Of course, we can also compose them to create bigger widgets. Now, that’s not something very interesting – after all we just added a piece of HTML below our previous HTML and it appeared below, so what’s the fun? Well, a bit of fun happens with the stylesheet and JS files (we don’t have a JS file here). Stylesheet got minified and added to the page stylesheet, returned in the header. If we had a JS file, it would also be included as a script (or file, depends on configuration) in the header. Of course, it may be that you actually want the JS to appear in the body – for this, Yesod offers toWidgetBody
and toWidgetHead
functions, which let you modify HTML head and body respectively. Widgets can be used not only for web pages – there are also functions – like toWidgetMedia
that can help you create all other types of data, including print styling or API.
One more note – if you wonder what a Widget
is, it is just an alias for WidgetT <<AppName>> IO ()
, where <<AppName>>
can be defined in Application.hs
(by default it’s MyApp
). It is important to note that Widget
is typed per-application. And we’ll discuss why exactly is it important next week, when discussing foundation datatype.
Stay tuned!
code
more code
~~~~