Search code examples
haskellihp

How do I change the <title> in an IHP app?


I see <title>App</title> is hardcoded in defaultLayout in Web/View/Layout.hs, and Web/View/Context.hs has

    let viewContext = ViewContext {
            requestContext = ?requestContext,
            user = currentUserOrNothing,
            flashMessages,
            controllerContext = ?controllerContext,
            layout = let ?viewContext = viewContext in defaultLayout
        }

but how do I use a different function for a specific View? The html function of the View class doesn't seem to return a new context, just a new html for part of the page.


Solution

  • There is now a pageTitle function you could use in view (e.g. your layout) like this:

    [hsx|
        <head>
            <title>{pageTitle}</title>
        </head>
    |]
    

    https://github.com/digitallyinduced/ihp/blob/18f104da69c526ff9e8ad3a6cdaedc6d39afb38c/IHP/PageTitle/ViewFunctions.hs#L54

    Which can in turn be set in action using setTitle

    action ShowProjectAction { projectId } = do
        project <- fetch projectId
        setTitle (get #title project)
    

    https://github.com/digitallyinduced/ihp/blob/d98c3d6eb8145d859c9ce461e7d1367be5be7337/IHP/PageTitle/ControllerFunctions.hs#L32

    Latest IHP also generates the following layout s.t. you get it automatically with a fallback:

    defaultLayout :: Html -> Html
    defaultLayout inner = H.docTypeHtml ! A.lang "en" $ [hsx|
    <head>
        {metaTags}
    
        {stylesheets}
        {scripts}
    
        <title>{pageTitleOrDefault "App"}</title>
    </head>
    <body>
        <div class="container mt-4">
            {renderFlashMessages}
            {inner}
        </div>
    </body>
    |]