This post will introduce some magic that you’ll use on a daily basis when using Yesod. This magic is mostly related to connection with the outside world – while Handler
and Widget
have IO in their type signatures, there are recommended ways of dealing with it – and this recommended way includes a foundation datatype.
Foundation datatype is a type that is accessible in all your Widget
‘s and Handler
‘s. In fact, it is even in the signature of your application – in Yesod App
, App
is your foundation datatype (that’s the name in the default scaffolding, you can change it if you wish to). You can keep anything there – default scaffolding puts there some server settings, connection pools, logger etc., but you can put virtually anything there – it’s just a typical data type.
This time we’re going to use it in a very simple way – to inject application name into the widgets and use it in the title – but on future posts we’ll be using the foundation value in much more sophisticated scenarios, such as database access or configuration. First let’s add the name to our data type – since this is just a tutorial, we’ll add it as a top-level field. So, in Foundation.hs
change the definition of data App
to
data App = App { appSettings :: AppSettings , appStatic :: Static -- ^ Settings for static file serving. , appConnPool :: ConnectionPool -- ^ Database connection pool. , appHttpManager :: Manager , appLogger :: Logger , appName :: Text }
Next step, initialization. In Application.hs
in code of makeFoundation
function add appName <- return "Project M"
line. That’s it, you already have your foundation data initialized. A little magic here is performed by the following line: let mkFoundation appConnPool = App {..}
– the {..}
syntax binds together names that exist in the scope and create a single data record. By the way, you can also use it the other way around: App {..} <- getYesod
will bring all the fields to the current scope. I believe it generally clutters the scope and should be avoided. Still, sometimes it can come in handy. getYesod
is a wrapped object of the foundation type, which is usually accessed by the syntax mentioned above (app <- getYesod
) – yet, it’s a typical Yesod value, so there is no real reason (except maybe convenience) to stick to this method.
In the last step we’re going to change Handler/Project.hs
and it’s rendering function. Let’s change the first two lines of renderPage
function to:
And that’s it, title on your development server should already change. I’ll change the display to format appName: projectName(projectId)
, by changing the where
clause from projectTitle = (toHtml projectId) ++ (toHtml projectName)
to projectTitle = (toHtml projectName) ++ "(" ++ (toHtml projectId) ++ ")"
.
That’s it for today – soon we’re going to explore the way of using databases with Yesod, but first – in the next post – we’ll have to deal with our data type and make it more useful.
Stay tuned!
code
more code
~~~~